@hasna/hooks 0.11.0 → 0.11.1

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/bin/index.js CHANGED
@@ -2516,7 +2516,7 @@ var init_codex_settings = __esm(() => {
2516
2516
  snapshots = new WeakMap;
2517
2517
  });
2518
2518
 
2519
- // ../../node_modules/.bun/@hasna+skills@0.9.17+a00d3064559565bb/node_modules/@hasna/skills/dist/index.js
2519
+ // node_modules/@hasna/skills/dist/index.js
2520
2520
  import { existsSync as existsSync10 } from "fs";
2521
2521
  import { homedir as homedir6 } from "os";
2522
2522
  import { join as join10, resolve as resolve4 } from "path";
@@ -35489,7 +35489,7 @@ var init_codex_safety_trust = __esm(() => {
35489
35489
  };
35490
35490
  });
35491
35491
 
35492
- // ../../node_modules/.bun/commander@12.1.0/node_modules/commander/lib/error.js
35492
+ // node_modules/commander/lib/error.js
35493
35493
  var require_error = __commonJS((exports) => {
35494
35494
  class CommanderError extends Error {
35495
35495
  constructor(exitCode, code2, message) {
@@ -35513,7 +35513,7 @@ var require_error = __commonJS((exports) => {
35513
35513
  exports.InvalidArgumentError = InvalidArgumentError;
35514
35514
  });
35515
35515
 
35516
- // ../../node_modules/.bun/commander@12.1.0/node_modules/commander/lib/argument.js
35516
+ // node_modules/commander/lib/argument.js
35517
35517
  var require_argument = __commonJS((exports) => {
35518
35518
  var { InvalidArgumentError } = require_error();
35519
35519
 
@@ -35592,7 +35592,7 @@ var require_argument = __commonJS((exports) => {
35592
35592
  exports.humanReadableArgName = humanReadableArgName;
35593
35593
  });
35594
35594
 
35595
- // ../../node_modules/.bun/commander@12.1.0/node_modules/commander/lib/help.js
35595
+ // node_modules/commander/lib/help.js
35596
35596
  var require_help = __commonJS((exports) => {
35597
35597
  var { humanReadableArgName } = require_argument();
35598
35598
 
@@ -35841,7 +35841,7 @@ var require_help = __commonJS((exports) => {
35841
35841
  exports.Help = Help;
35842
35842
  });
35843
35843
 
35844
- // ../../node_modules/.bun/commander@12.1.0/node_modules/commander/lib/option.js
35844
+ // node_modules/commander/lib/option.js
35845
35845
  var require_option = __commonJS((exports) => {
35846
35846
  var { InvalidArgumentError } = require_error();
35847
35847
 
@@ -35992,7 +35992,7 @@ var require_option = __commonJS((exports) => {
35992
35992
  exports.DualOptions = DualOptions;
35993
35993
  });
35994
35994
 
35995
- // ../../node_modules/.bun/commander@12.1.0/node_modules/commander/lib/suggestSimilar.js
35995
+ // node_modules/commander/lib/suggestSimilar.js
35996
35996
  var require_suggestSimilar = __commonJS((exports) => {
35997
35997
  var maxDistance = 3;
35998
35998
  function editDistance(a, b) {
@@ -36065,7 +36065,7 @@ var require_suggestSimilar = __commonJS((exports) => {
36065
36065
  exports.suggestSimilar = suggestSimilar;
36066
36066
  });
36067
36067
 
36068
- // ../../node_modules/.bun/commander@12.1.0/node_modules/commander/lib/command.js
36068
+ // node_modules/commander/lib/command.js
36069
36069
  var require_command = __commonJS((exports) => {
36070
36070
  var EventEmitter = __require("events").EventEmitter;
36071
36071
  var childProcess = __require("child_process");
@@ -37308,7 +37308,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
37308
37308
  exports.Command = Command;
37309
37309
  });
37310
37310
 
37311
- // ../../node_modules/.bun/commander@12.1.0/node_modules/commander/index.js
37311
+ // node_modules/commander/index.js
37312
37312
  var require_commander = __commonJS((exports) => {
37313
37313
  var { Argument } = require_argument();
37314
37314
  var { Command } = require_command();
@@ -37328,7 +37328,7 @@ var require_commander = __commonJS((exports) => {
37328
37328
  exports.InvalidOptionArgumentError = InvalidArgumentError;
37329
37329
  });
37330
37330
 
37331
- // ../../node_modules/.bun/cli-spinners@2.9.2/node_modules/cli-spinners/spinners.json
37331
+ // node_modules/cli-spinners/spinners.json
37332
37332
  var require_spinners = __commonJS((exports, module) => {
37333
37333
  module.exports = {
37334
37334
  dots: {
@@ -38954,7 +38954,7 @@ var require_spinners = __commonJS((exports, module) => {
38954
38954
  };
38955
38955
  });
38956
38956
 
38957
- // ../../node_modules/.bun/cli-spinners@2.9.2/node_modules/cli-spinners/index.js
38957
+ // node_modules/cli-spinners/index.js
38958
38958
  var require_cli_spinners = __commonJS((exports, module) => {
38959
38959
  var spinners = Object.assign({}, require_spinners());
38960
38960
  var spinnersList = Object.keys(spinners);
@@ -39035,10 +39035,10 @@ var init_redact = __esm(() => {
39035
39035
 
39036
39036
  // src/lib/profiles.ts
39037
39037
  import { existsSync as existsSync14, mkdirSync as mkdirSync13, readFileSync as readFileSync19, writeFileSync as writeFileSync12, readdirSync as readdirSync8, rmSync, cpSync as cpSync2 } from "fs";
39038
- import { join as join29 } from "path";
39038
+ import { join as join27 } from "path";
39039
39039
  function getProfilesDir() {
39040
- const newDir = join29(getEffectiveDataRoot(), "profiles");
39041
- const oldDir = join29(getHomeDir(), ".hooks", "profiles");
39040
+ const newDir = join27(getEffectiveDataRoot(), "profiles");
39041
+ const oldDir = join27(getHomeDir(), ".hooks", "profiles");
39042
39042
  if (!existsSync14(newDir) && existsSync14(oldDir)) {
39043
39043
  mkdirSync13(newDir, { recursive: true });
39044
39044
  cpSync2(oldDir, newDir, { recursive: true });
@@ -39052,7 +39052,7 @@ function ensureProfilesDir() {
39052
39052
  }
39053
39053
  }
39054
39054
  function profilePath(id) {
39055
- return join29(getProfilesDir(), `${id}.json`);
39055
+ return join27(getProfilesDir(), `${id}.json`);
39056
39056
  }
39057
39057
  function shortUuid() {
39058
39058
  return crypto.randomUUID().slice(0, 8);
@@ -39094,7 +39094,7 @@ function listProfiles() {
39094
39094
  const profiles = [];
39095
39095
  for (const file2 of files) {
39096
39096
  try {
39097
- const content = readFileSync19(join29(dir, file2), "utf-8");
39097
+ const content = readFileSync19(join27(dir, file2), "utf-8");
39098
39098
  profiles.push(JSON.parse(content));
39099
39099
  } catch {}
39100
39100
  }
@@ -39138,18 +39138,18 @@ var init_profiles = __esm(() => {
39138
39138
  init_app_home();
39139
39139
  });
39140
39140
 
39141
- // ../../node_modules/.bun/@hasna+contracts@1.2.2+944b86d8024e79fa/node_modules/@hasna/contracts/dist/client/transport.js
39142
- import { isIP as isIP2 } from "net";
39141
+ // node_modules/@hasna/contracts/dist/client/transport.js
39142
+ import { isIP } from "net";
39143
39143
  import { spawnSync as spawnSync2 } from "child_process";
39144
39144
  import { closeSync as closeSync22, fstatSync as fstatSync22, openSync as openSync22, readFileSync as readFileSync22 } from "fs";
39145
39145
  import { O_NOFOLLOW as O_NOFOLLOW2, O_NONBLOCK as O_NONBLOCK2, O_RDONLY as O_RDONLY2 } from "constants";
39146
39146
  import { hostname as osHostname } from "os";
39147
39147
  import { isAbsolute as isAbsolute21, join as join28 } from "path";
39148
- import { createRequire as createRequire3 } from "module";
39148
+ import { createRequire as createRequire2 } from "module";
39149
39149
  import { fileURLToPath as fileURLToPath22 } from "url";
39150
39150
  import { closeSync as closeSync20, fstatSync as fstatSync19, lstatSync as lstatSync24, openSync as openSync20, readFileSync as readFileSync20, realpathSync as realpathSync12, statSync as statSync2 } from "fs";
39151
39151
  import { O_NOFOLLOW, O_NONBLOCK, O_RDONLY } from "constants";
39152
- import { basename as basename9, dirname as dirname22, join as join30, relative as relative5, sep as sep6 } from "path";
39152
+ import { basename as basename9, dirname as dirname22, join as join29, relative as relative5, sep as sep6 } from "path";
39153
39153
  import { fileURLToPath as fileURLToPath3, pathToFileURL } from "url";
39154
39154
  function envToken2(name) {
39155
39155
  return name.toUpperCase().replace(/-/g, "_");
@@ -39224,11 +39224,11 @@ function o(e2, r2, t2) {
39224
39224
  }
39225
39225
  function entryPoint(directory2) {
39226
39226
  const root = realpathSync12(directory2);
39227
- const fd = openSync20(join30(root, "package.json"), O_RDONLY | O_NOFOLLOW | O_NONBLOCK);
39227
+ const fd = openSync20(join29(root, "package.json"), O_RDONLY | O_NOFOLLOW | O_NONBLOCK);
39228
39228
  let pkg;
39229
39229
  try {
39230
39230
  const stat2 = fstatSync19(fd);
39231
- if (!stat2.isFile() || stat2.size > MAX_PACKAGE_BYTES3)
39231
+ if (!stat2.isFile() || stat2.size > MAX_PACKAGE_BYTES2)
39232
39232
  throw new Error("Invalid Secrets package metadata");
39233
39233
  pkg = JSON.parse(readFileSync20(fd, "utf8"));
39234
39234
  } finally {
@@ -39244,7 +39244,7 @@ function entryPoint(directory2) {
39244
39244
  if (/[\\%?#\0]/.test(target) || parts.some((part) => !part || part === "." || part === ".." || part === "node_modules")) {
39245
39245
  throw new Error("Invalid Secrets import export");
39246
39246
  }
39247
- const file2 = realpathSync12(join30(root, ...parts));
39247
+ const file2 = realpathSync12(join29(root, ...parts));
39248
39248
  const within = relative5(root, file2);
39249
39249
  if (!within || within === ".." || within.startsWith(`..${sep6}`) || !statSync2(file2).isFile()) {
39250
39250
  throw new Error("Secrets import export escapes its package or is not a file");
@@ -39255,7 +39255,7 @@ function resolveInstalledSecrets(parentUrl) {
39255
39255
  let directory2 = dirname22(fileURLToPath3(parentUrl));
39256
39256
  for (;; ) {
39257
39257
  if (basename9(directory2) !== "node_modules") {
39258
- const candidate = join30(directory2, "node_modules", PACKAGE);
39258
+ const candidate = join29(directory2, "node_modules", PACKAGE);
39259
39259
  let absent = false;
39260
39260
  try {
39261
39261
  lstatSync24(candidate);
@@ -39375,7 +39375,7 @@ function readAppConfigFile(path) {
39375
39375
  const uid2 = process.getuid?.() ?? process.geteuid?.();
39376
39376
  if (uid2 !== undefined && before.uid !== uid2)
39377
39377
  unsafe("the file is not owned by the current user");
39378
- if (before.size > MAX_CREDENTIAL_FILE_BYTES3)
39378
+ if (before.size > MAX_CREDENTIAL_FILE_BYTES2)
39379
39379
  unsafe("the file exceeds the size limit");
39380
39380
  const bytes = readFileSync22(fd);
39381
39381
  const after = fstatSync22(fd);
@@ -39467,13 +39467,13 @@ function sealCredential(fields) {
39467
39467
  configurable: false
39468
39468
  });
39469
39469
  }
39470
- Object.defineProperty(sealed, INSPECT_CUSTOM3, {
39470
+ Object.defineProperty(sealed, INSPECT_CUSTOM2, {
39471
39471
  value: () => ({ ...visible, apiKey: "[redacted]" }),
39472
39472
  enumerable: false,
39473
39473
  writable: false,
39474
39474
  configurable: false
39475
39475
  });
39476
- Object.defineProperty(sealed, CREDENTIAL_SEAL3, {
39476
+ Object.defineProperty(sealed, CREDENTIAL_SEAL2, {
39477
39477
  value: true,
39478
39478
  enumerable: false,
39479
39479
  writable: false,
@@ -39504,7 +39504,7 @@ function firstEnvValue(env, keys2) {
39504
39504
  return null;
39505
39505
  }
39506
39506
  function isAmbientEnvironment(env) {
39507
- return env === process.env || env[AMBIENT_ENVIRONMENT3] === true;
39507
+ return env === process.env || env[AMBIENT_ENVIRONMENT2] === true;
39508
39508
  }
39509
39509
  function defaultKeychainRunner(argv) {
39510
39510
  const result = spawnSync2(KEYCHAIN_SECURITY_BIN, [...argv], {
@@ -39598,7 +39598,7 @@ function snapshotClientEnvironment(name, env) {
39598
39598
  snapshot2[key] = descriptor.value;
39599
39599
  }
39600
39600
  if (ambient) {
39601
- Object.defineProperty(snapshot2, AMBIENT_ENVIRONMENT3, {
39601
+ Object.defineProperty(snapshot2, AMBIENT_ENVIRONMENT2, {
39602
39602
  value: true,
39603
39603
  enumerable: false,
39604
39604
  writable: false,
@@ -39771,7 +39771,7 @@ async function completePointerCredential(name, pointerResolution, env = process.
39771
39771
  let secretsSdk;
39772
39772
  try {
39773
39773
  const sdkUrl = resolveInstalledSecrets(import.meta.url);
39774
- secretsSdk = requireSecretsSdk3(fileURLToPath22(sdkUrl));
39774
+ secretsSdk = requireSecretsSdk2(fileURLToPath22(sdkUrl));
39775
39775
  } catch {
39776
39776
  throw new CredentialResolutionError(name, `${pointerEnvKey} names vault item '${vaultKey}', but the secrets SDK (@hasna/secrets) is not installed ` + `in this process. A vault pointer is TERMINAL: install @hasna/secrets to resolve it, or unset ${pointerEnvKey}.`, [pointerEnvKey]);
39777
39777
  }
@@ -39855,7 +39855,7 @@ function canonicalAuthorityHostname(authority) {
39855
39855
  }
39856
39856
  assertCanonicalPort(portSuffix.slice(1));
39857
39857
  }
39858
- if (isIP2(rawHostname.slice(1, -1)) !== 6) {
39858
+ if (isIP(rawHostname.slice(1, -1)) !== 6) {
39859
39859
  throw new Error("API URL authority must contain a canonical IPv6 literal.");
39860
39860
  }
39861
39861
  } else {
@@ -39871,7 +39871,7 @@ function canonicalAuthorityHostname(authority) {
39871
39871
  } else {
39872
39872
  rawHostname = authority;
39873
39873
  }
39874
- const ipVersion = isIP2(rawHostname);
39874
+ const ipVersion = isIP(rawHostname);
39875
39875
  const numericAddressParts = rawHostname.split(".");
39876
39876
  const looksLikeNonCanonicalIpv4 = numericAddressParts.every((part) => /^(?:0x[0-9a-f]+|[0-9]+)$/i.test(part));
39877
39877
  if (ipVersion !== 4 && looksLikeNonCanonicalIpv4 || ipVersion !== 4 && !isValidDnsDomain(rawHostname.toLowerCase())) {
@@ -40007,9 +40007,9 @@ function credentialDiskSourcesForMessage(name, env) {
40007
40007
  const paths = credentialDiskSources(name, env);
40008
40008
  return paths.length > 0 ? paths.join(" or ") : "<no HOME or HASNA_HOME set in this environment, so no credential file was consulted>";
40009
40009
  }
40010
- var CREDENTIAL_PROFILE_ENV_KEY = "HASNA_PROFILE", PACKAGE = "@hasna/secrets", MAX_PACKAGE_BYTES3, CredentialResolutionError, CredentialFileUnsafeError, HASNA_HOME_ENV_KEY = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY = "HASNA_STATION", HASNA_HOME_DIR = ".hasna", CONFIG_SUBDIR = "config", CREDENTIALS_FILE = "credentials", KEYCHAIN_SECURITY_BIN = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS = 44, KEYCHAIN_SPAWN_TIMEOUT_MS = 1e4, MAX_CREDENTIAL_FILE_BYTES3, SAFE_APP_SLUG, SAFE_PROFILE, ILLEGAL_IN_HEADER_VALUE, VAULT_POINTER_SHAPE, CREDENTIAL_SHAPED_KEY, INSPECT_CUSTOM3, CREDENTIAL_SEAL3, AMBIENT_ENVIRONMENT3, requireSecretsSdk3, DEFAULT_FLEET_GATEWAY_ORIGIN = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN, DNS_LABEL_PATTERN, ClientTransportConfigurationError, IDEMPOTENT_METHODS3, AUTHORITY_OVERRIDE_HEADERS3;
40010
+ var CREDENTIAL_PROFILE_ENV_KEY = "HASNA_PROFILE", PACKAGE = "@hasna/secrets", MAX_PACKAGE_BYTES2, CredentialResolutionError, CredentialFileUnsafeError, HASNA_HOME_ENV_KEY = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY = "HASNA_STATION", HASNA_HOME_DIR = ".hasna", CONFIG_SUBDIR = "config", CREDENTIALS_FILE = "credentials", KEYCHAIN_SECURITY_BIN = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS = 44, KEYCHAIN_SPAWN_TIMEOUT_MS = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG, SAFE_PROFILE, ILLEGAL_IN_HEADER_VALUE, VAULT_POINTER_SHAPE, CREDENTIAL_SHAPED_KEY, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, AMBIENT_ENVIRONMENT2, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN, DNS_LABEL_PATTERN, ClientTransportConfigurationError, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2;
40011
40011
  var init_transport = __esm(() => {
40012
- MAX_PACKAGE_BYTES3 = 1024 * 1024;
40012
+ MAX_PACKAGE_BYTES2 = 1024 * 1024;
40013
40013
  CredentialResolutionError = class CredentialResolutionError extends Error {
40014
40014
  appName;
40015
40015
  attempted;
@@ -40028,16 +40028,16 @@ var init_transport = __esm(() => {
40028
40028
  this.path = path;
40029
40029
  }
40030
40030
  };
40031
- MAX_CREDENTIAL_FILE_BYTES3 = 64 * 1024;
40031
+ MAX_CREDENTIAL_FILE_BYTES2 = 64 * 1024;
40032
40032
  SAFE_APP_SLUG = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
40033
40033
  SAFE_PROFILE = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
40034
40034
  ILLEGAL_IN_HEADER_VALUE = /[^\t\x20-\x7e]/;
40035
40035
  VAULT_POINTER_SHAPE = /^[a-z0-9][a-z0-9-]*(?:\/[a-z0-9][a-z0-9-_.]*){2,}$/;
40036
40036
  CREDENTIAL_SHAPED_KEY = /(?:^|_)(?:API_KEY|KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH)(?:_|$)/;
40037
- INSPECT_CUSTOM3 = Symbol.for("nodejs.util.inspect.custom");
40038
- CREDENTIAL_SEAL3 = Symbol.for("hasna:contracts:sealedCredential");
40039
- AMBIENT_ENVIRONMENT3 = Symbol.for("hasna:contracts:ambientClientEnvironment");
40040
- requireSecretsSdk3 = createRequire3(import.meta.url);
40037
+ INSPECT_CUSTOM2 = Symbol.for("nodejs.util.inspect.custom");
40038
+ CREDENTIAL_SEAL2 = Symbol.for("hasna:contracts:sealedCredential");
40039
+ AMBIENT_ENVIRONMENT2 = Symbol.for("hasna:contracts:ambientClientEnvironment");
40040
+ requireSecretsSdk2 = createRequire2(import.meta.url);
40041
40041
  ASCII_CONTROL_PATTERN = /[\u0000-\u001f\u007f]/;
40042
40042
  DNS_LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
40043
40043
  ClientTransportConfigurationError = class ClientTransportConfigurationError extends Error {
@@ -40050,8 +40050,8 @@ var init_transport = __esm(() => {
40050
40050
  this.sources = Object.freeze([...sources]);
40051
40051
  }
40052
40052
  };
40053
- IDEMPOTENT_METHODS3 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
40054
- AUTHORITY_OVERRIDE_HEADERS3 = new Set([
40053
+ IDEMPOTENT_METHODS2 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
40054
+ AUTHORITY_OVERRIDE_HEADERS2 = new Set([
40055
40055
  "host",
40056
40056
  ":authority",
40057
40057
  "forwarded",
@@ -40562,7 +40562,7 @@ __export(exports_run, {
40562
40562
  });
40563
40563
  import { randomBytes as randomBytes2 } from "crypto";
40564
40564
  import { rmSync as rmSync2, writeFileSync as writeFileSync13 } from "fs";
40565
- import { basename as basename11, dirname as dirname24, isAbsolute as isAbsolute25, join as join31 } from "path";
40565
+ import { basename as basename11, dirname as dirname24, isAbsolute as isAbsolute25, join as join30 } from "path";
40566
40566
  function extensionOf(scriptPath) {
40567
40567
  const base = basename11(scriptPath);
40568
40568
  const dot = base.lastIndexOf(".");
@@ -40633,7 +40633,7 @@ async function readPipeWithDeadline(stream, deadlineMs) {
40633
40633
  async function executeVerifiedScript(options) {
40634
40634
  const scriptDir = dirname24(options.scriptPath);
40635
40635
  const interpreter = interpreterFor(options.name, options.scriptPath, options.content);
40636
- const tempPath = join31(scriptDir, `.hooks-verified-${randomBytes2(12).toString("hex")}.${interpreter.tempExt}`);
40636
+ const tempPath = join30(scriptDir, `.hooks-verified-${randomBytes2(12).toString("hex")}.${interpreter.tempExt}`);
40637
40637
  let proc = null;
40638
40638
  let timedOut = false;
40639
40639
  const timeoutTimer = options.timeout ? setTimeout(() => {
@@ -40725,10 +40725,10 @@ __export(exports_custom_install, {
40725
40725
  ensureCustomDir: () => ensureCustomDir
40726
40726
  });
40727
40727
  import { existsSync as existsSync16, mkdirSync as mkdirSync14, mkdtempSync, readFileSync as readFileSync21, rmSync as rmSync4 } from "fs";
40728
- import { join as join32 } from "path";
40728
+ import { join as join31 } from "path";
40729
40729
  import { tmpdir as tmpdir2 } from "os";
40730
40730
  function manifestAt(dir) {
40731
- const path = join32(dir, "manifest.json");
40731
+ const path = join31(dir, "manifest.json");
40732
40732
  if (!existsSync16(path))
40733
40733
  return;
40734
40734
  try {
@@ -40751,8 +40751,8 @@ function writeFromManifest(manifest, srcDir, source, kind) {
40751
40751
  return { name, version: manifest.version, kind, source, dir, scriptPath };
40752
40752
  }
40753
40753
  async function cloneToTemp(gitUrl) {
40754
- const tmp = mkdtempSync(join32(tmpdir2(), "hooks-install-"));
40755
- const proc = Bun.spawn(["git", "clone", "--depth", "1", "--quiet", gitUrl, join32(tmp, "repo")], {
40754
+ const tmp = mkdtempSync(join31(tmpdir2(), "hooks-install-"));
40755
+ const proc = Bun.spawn(["git", "clone", "--depth", "1", "--quiet", gitUrl, join31(tmp, "repo")], {
40756
40756
  stdout: "pipe",
40757
40757
  stderr: "pipe"
40758
40758
  });
@@ -40765,7 +40765,7 @@ async function cloneToTemp(gitUrl) {
40765
40765
  rmSync4(tmp, { recursive: true, force: true });
40766
40766
  throw new Error(`git clone failed (${exitCode}): ${stderr.trim()}`);
40767
40767
  }
40768
- return join32(tmp, "repo");
40768
+ return join31(tmp, "repo");
40769
40769
  }
40770
40770
  function isGitUrl(value) {
40771
40771
  return value.startsWith("git@") || value.startsWith("ssh://") || value.startsWith("file://") || value.endsWith(".git");
@@ -42004,11 +42004,11 @@ __export(exports_serve, {
42004
42004
  DEFAULT_SERVE_PORT: () => DEFAULT_SERVE_PORT
42005
42005
  });
42006
42006
  import { readFileSync as readFileSync25 } from "fs";
42007
- import { dirname as dirname25, join as join33 } from "path";
42007
+ import { dirname as dirname25, join as join32 } from "path";
42008
42008
  import { fileURLToPath as fileURLToPath4 } from "url";
42009
42009
  function packageVersion() {
42010
42010
  try {
42011
- const pkgPath = join33(dirname25(fileURLToPath4(import.meta.url)), "..", "package.json");
42011
+ const pkgPath = join32(dirname25(fileURLToPath4(import.meta.url)), "..", "package.json");
42012
42012
  return JSON.parse(readFileSync25(pkgPath, "utf-8")).version || "0.0.0";
42013
42013
  } catch {
42014
42014
  return "0.0.0";
@@ -42310,7 +42310,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
42310
42310
  import { z as z3 } from "zod";
42311
42311
  import { createServer } from "http";
42312
42312
  import { existsSync as existsSync17, readFileSync as readFileSync26 } from "fs";
42313
- import { join as join34, dirname as dirname26 } from "path";
42313
+ import { join as join33, dirname as dirname26 } from "path";
42314
42314
  import { fileURLToPath as fileURLToPath5 } from "url";
42315
42315
  async function runVerifiedHook(name, stdin, timeoutMs) {
42316
42316
  const { resolveHook: resolveHook2, resolveScriptPath: resolveScriptPath2 } = await Promise.resolve().then(() => (init_resolve(), exports_resolve));
@@ -42544,7 +42544,7 @@ function createHooksServer() {
42544
42544
  continue;
42545
42545
  }
42546
42546
  const hookDir = getHookPath(name);
42547
- if (!existsSync17(join34(hookDir, "src", "hook.ts"))) {
42547
+ if (!existsSync17(join33(hookDir, "src", "hook.ts"))) {
42548
42548
  issues.push({ hook: name, issue: "Missing src/hook.ts in package", severity: "error" });
42549
42549
  hookHealthy = false;
42550
42550
  }
@@ -42588,7 +42588,7 @@ function createHooksServer() {
42588
42588
  return { content: [{ type: "text", text: JSON.stringify({ error: `Hook '${name}' not found` }) }] };
42589
42589
  }
42590
42590
  const hookPath = getHookPath(name);
42591
- const readmePath = join34(hookPath, "README.md");
42591
+ const readmePath = join33(hookPath, "README.md");
42592
42592
  let readme = "";
42593
42593
  if (existsSync17(readmePath)) {
42594
42594
  readme = readFileSync26(readmePath, "utf-8");
@@ -43318,7 +43318,7 @@ var init_server = __esm(() => {
43318
43318
  pkg = { name: "@hasna/hooks", version: "0.0.0" };
43319
43319
  try {
43320
43320
  for (const rel of ["../../package.json", "../package.json", "../../../package.json"]) {
43321
- const p = join34(__dirname3, rel);
43321
+ const p = join33(__dirname3, rel);
43322
43322
  if (existsSync17(p)) {
43323
43323
  pkg = JSON.parse(readFileSync26(p, "utf-8"));
43324
43324
  break;
@@ -43397,7 +43397,7 @@ __export(exports_native_readiness_binding, {
43397
43397
  import { createHash as createHash25, randomUUID as randomUUID8 } from "crypto";
43398
43398
  import { closeSync as closeSync21, constants as constants19, fsyncSync as fsyncSync8, lstatSync as lstatSync25, mkdirSync as mkdirSync15, openSync as openSync21, realpathSync as realpathSync14, writeFileSync as writeFileSync14 } from "fs";
43399
43399
  import { homedir as homedir15 } from "os";
43400
- import { dirname as dirname27, join as join35 } from "path";
43400
+ import { dirname as dirname27, join as join34 } from "path";
43401
43401
  function need10(value, code2) {
43402
43402
  if (!value)
43403
43403
  throw new ReadinessBindingError(code2);
@@ -43455,7 +43455,7 @@ async function registerTrashReadinessBinding(input2, expectedSHA256) {
43455
43455
  const operationId = randomUUID8();
43456
43456
  let directory2 = home;
43457
43457
  for (const part of [".hasna", "hooks", "native", "trash-readiness"]) {
43458
- directory2 = join35(directory2, part);
43458
+ directory2 = join34(directory2, part);
43459
43459
  try {
43460
43460
  mkdirSync15(directory2, { mode: 448 });
43461
43461
  syncDirectory4(dirname27(directory2));
@@ -43465,12 +43465,12 @@ async function registerTrashReadinessBinding(input2, expectedSHA256) {
43465
43465
  }
43466
43466
  safeDirectory4(directory2);
43467
43467
  }
43468
- const operation = join35(directory2, operationId);
43468
+ const operation = join34(directory2, operationId);
43469
43469
  mkdirSync15(operation, { mode: 448 });
43470
43470
  syncDirectory4(directory2);
43471
43471
  if (before)
43472
- exclusive3(join35(operation, "binding.before"), before.raw);
43473
- exclusive3(join35(operation, "intent.json"), JSON.stringify({ operationId, target, expectedSHA256, desiredSHA256: digest4 }) + `
43472
+ exclusive3(join34(operation, "binding.before"), before.raw);
43473
+ exclusive3(join34(operation, "intent.json"), JSON.stringify({ operationId, target, expectedSHA256, desiredSHA256: digest4 }) + `
43474
43474
  `);
43475
43475
  try {
43476
43476
  need10((read4()?.sha256 ?? "absent") === expectedSHA256, "binding_changed");
@@ -43484,7 +43484,7 @@ async function registerTrashReadinessBinding(input2, expectedSHA256) {
43484
43484
  syncDirectory4(directory2);
43485
43485
  need10(read4()?.sha256 === digest4, "binding_changed");
43486
43486
  const receipt = { ok: true, changed: true, operationId, path: target, sha256: digest4, configurationReady: true, nativeAdoptionVerified: false };
43487
- exclusive3(join35(operation, "receipt.json"), JSON.stringify(receipt) + `
43487
+ exclusive3(join34(operation, "receipt.json"), JSON.stringify(receipt) + `
43488
43488
  `);
43489
43489
  return receipt;
43490
43490
  } catch {
@@ -43508,7 +43508,7 @@ var init_native_readiness_binding = __esm(() => {
43508
43508
 
43509
43509
  // src/cli/index.tsx
43510
43510
  init_native_safety_registration();
43511
- import { resolve as resolve23 } from "path";
43511
+ import { resolve as resolve21 } from "path";
43512
43512
 
43513
43513
  // src/lib/claude-safety-check.ts
43514
43514
  init_native_safety();
@@ -43627,25 +43627,16 @@ async function verifyClaudeSafetyConfiguration(options = {}, dependencies = {})
43627
43627
  // src/cli/index.tsx
43628
43628
  init_codex_safety_trust();
43629
43629
 
43630
- // ../events/dist/commander.js
43630
+ // node_modules/@hasna/events/dist/commander.js
43631
43631
  import { chmod, mkdir, readFile as readFile2, rename, writeFile } from "fs/promises";
43632
43632
  import { Buffer as Buffer2 } from "buffer";
43633
- import { existsSync as existsSync22 } from "fs";
43634
- import { join as join22 } from "path";
43635
43633
  import { existsSync as existsSync13 } from "fs";
43636
43634
  import { homedir as homedir13 } from "os";
43637
- import { join as join20, resolve as resolve20 } from "path";
43638
- import { homedir as pathsResolverHomedir3 } from "os";
43639
- import { join as pathsResolverJoin3 } from "path";
43635
+ import { join as join20 } from "path";
43640
43636
  import { createHmac, timingSafeEqual } from "crypto";
43641
- import { lookup as dnsLookup } from "dns/promises";
43642
- import { isIP } from "net";
43643
43637
  import { randomUUID as randomUUID7 } from "crypto";
43644
43638
  import { spawn as spawn3 } from "child_process";
43645
- import { request as nodeHttpRequest } from "http";
43646
- import { request as nodeHttpsRequest } from "https";
43647
43639
  import { randomUUID as randomUUID22 } from "crypto";
43648
- import { createRequire as createRequire2 } from "module";
43649
43640
  function getPathValue(input2, path) {
43650
43641
  return path.split(".").reduce((value, part) => {
43651
43642
  if (value && typeof value === "object" && part in value) {
@@ -43741,103 +43732,13 @@ function channelMatchesEvent(channel, event) {
43741
43732
  return true;
43742
43733
  return channel.filters.some((filter) => eventMatchesFilter(event, filter));
43743
43734
  }
43744
- var PATHS_RESOLVER_KIND_ENV2 = {
43745
- config: "HASNA_CONFIG_HOME",
43746
- data: "HASNA_DATA_HOME",
43747
- state: "HASNA_STATE_HOME",
43748
- cache: "HASNA_CACHE_HOME"
43749
- };
43750
- var PATHS_RESOLVER_APP_SLUG_RE3 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
43751
- function pathsResolverAssertApp3(app) {
43752
- if (typeof app !== "string" || app.length === 0) {
43753
- throw new TypeError("paths: app must be a non-empty string");
43754
- }
43755
- if (!PATHS_RESOLVER_APP_SLUG_RE3.test(app)) {
43756
- throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
43757
- }
43758
- }
43759
- function pathsResolverAssertKind2(kind) {
43760
- if (!Object.keys(PATHS_RESOLVER_KIND_ENV2).includes(kind)) {
43761
- throw new TypeError(`paths: invalid path kind "${kind}" \u2014 expected one of ${Object.keys(PATHS_RESOLVER_KIND_ENV2).join(", ")}`);
43762
- }
43763
- }
43764
- function pathsResolverBaseDir2(kind, options) {
43765
- pathsResolverAssertKind2(kind);
43766
- const env = options.env ?? process.env;
43767
- const override = env[PATHS_RESOLVER_KIND_ENV2[kind]];
43768
- if (typeof override === "string" && override.length > 0)
43769
- return override;
43770
- const home = options.home ?? pathsResolverHomedir3();
43771
- const platform = options.platform ?? process.platform;
43772
- if (platform === "darwin") {
43773
- switch (kind) {
43774
- case "config":
43775
- case "data":
43776
- return pathsResolverJoin3(home, "Library", "Application Support", "Hasna");
43777
- case "cache":
43778
- return pathsResolverJoin3(home, "Library", "Caches", "Hasna");
43779
- case "state":
43780
- return pathsResolverJoin3(home, "Library", "Logs", "Hasna");
43781
- }
43782
- }
43783
- switch (kind) {
43784
- case "config":
43785
- return pathsResolverJoin3(home, ".config", "hasna");
43786
- case "data":
43787
- return pathsResolverJoin3(home, ".local", "share", "hasna");
43788
- case "state":
43789
- return pathsResolverJoin3(home, ".local", "state", "hasna");
43790
- case "cache":
43791
- return pathsResolverJoin3(home, ".cache", "hasna");
43792
- }
43793
- }
43794
- function pathsResolverResolve2(kind, options) {
43795
- pathsResolverAssertApp3(options.app);
43796
- const appSegment = options.internal === true ? pathsResolverJoin3("internal", options.app) : options.app;
43797
- return pathsResolverJoin3(pathsResolverBaseDir2(kind, options), appSegment);
43798
- }
43799
- function dataDir3(options) {
43800
- return pathsResolverResolve2("data", options);
43801
- }
43802
43735
  var HASNA_EVENTS_DIR_ENV = "HASNA_EVENTS_DIR";
43803
43736
  var HASNA_EVENTS_HOME_ENV = "HASNA_EVENTS_HOME";
43804
- var EVENTS_STORE_SENTINEL_FILE = "events.json";
43805
- function effectiveHome2() {
43806
- return process.env["HOME"] || process.env["USERPROFILE"] || homedir13();
43807
- }
43808
- function legacyHomeDir() {
43809
- return join20(effectiveHome2(), ".hasna", "events");
43810
- }
43811
- function resolverHome() {
43812
- return dataDir3({ app: "events", home: effectiveHome2() || undefined });
43813
- }
43814
- function adoptResolverHome(resolved, env = process.env) {
43815
- const dataOverride = env.HASNA_DATA_HOME;
43816
- if (typeof dataOverride === "string" && dataOverride.trim().length > 0)
43817
- return true;
43818
- return existsSync13(join20(resolved, EVENTS_STORE_SENTINEL_FILE));
43819
- }
43820
- function exactEventsHome() {
43821
- const dir = process.env[HASNA_EVENTS_DIR_ENV];
43822
- if (dir && dir.trim())
43823
- return dir.trim();
43824
- const home = process.env[HASNA_EVENTS_HOME_ENV];
43825
- if (home && home.trim())
43826
- return home.trim();
43827
- return;
43828
- }
43829
- function getEventsHome() {
43830
- const exact2 = exactEventsHome();
43831
- if (exact2)
43832
- return resolve20(exact2);
43833
- const resolved = resolverHome();
43834
- return adoptResolverHome(resolved) ? resolve20(resolved) : resolve20(legacyHomeDir());
43835
- }
43836
43737
  var LOCAL_JSON_EVENT_CURSOR_PREFIX = "local-json-v1:";
43837
43738
  var DEFAULT_EVENT_PAGE_LIMIT = 100;
43838
43739
  var MAX_EVENT_PAGE_LIMIT = 1000;
43839
43740
  function getEventsDataDir(override) {
43840
- return override || getEventsHome();
43741
+ return override || process.env[HASNA_EVENTS_DIR_ENV] || process.env[HASNA_EVENTS_HOME_ENV] || join20(homedir13(), ".hasna", "events");
43841
43742
  }
43842
43743
  function getActiveEventsDirEnv() {
43843
43744
  if (process.env[HASNA_EVENTS_DIR_ENV])
@@ -43853,12 +43754,12 @@ class JsonEventsStore {
43853
43754
  channelsPath;
43854
43755
  eventsPath;
43855
43756
  deliveriesPath;
43856
- constructor(dataDir22 = getEventsDataDir()) {
43857
- this.dataDir = dataDir22;
43858
- this.runtime = localJsonRuntime(dataDir22);
43859
- this.channelsPath = join22(dataDir22, "channels.json");
43860
- this.eventsPath = join22(dataDir22, "events.json");
43861
- this.deliveriesPath = join22(dataDir22, "deliveries.json");
43757
+ constructor(dataDir3 = getEventsDataDir()) {
43758
+ this.dataDir = dataDir3;
43759
+ this.runtime = localJsonRuntime(dataDir3);
43760
+ this.channelsPath = join20(dataDir3, "channels.json");
43761
+ this.eventsPath = join20(dataDir3, "events.json");
43762
+ this.deliveriesPath = join20(dataDir3, "deliveries.json");
43862
43763
  }
43863
43764
  async init() {
43864
43765
  await mkdir(this.dataDir, { recursive: true, mode: 448 });
@@ -43975,7 +43876,7 @@ class JsonEventsStore {
43975
43876
  };
43976
43877
  }
43977
43878
  async ensureArrayFile(path) {
43978
- if (!existsSync22(path)) {
43879
+ if (!existsSync13(path)) {
43979
43880
  await writeFile(path, `[]
43980
43881
  `, { encoding: "utf-8", mode: 384 });
43981
43882
  }
@@ -44005,7 +43906,7 @@ class JsonEventsStore {
44005
43906
  });
44006
43907
  }
44007
43908
  }
44008
- function localJsonRuntime(dataDir22 = getEventsDataDir()) {
43909
+ function localJsonRuntime(dataDir3 = getEventsDataDir()) {
44009
43910
  return {
44010
43911
  mode: "local-files",
44011
43912
  name: "json-events-store",
@@ -44018,7 +43919,7 @@ function localJsonRuntime(dataDir22 = getEventsDataDir()) {
44018
43919
  durable: true,
44019
43920
  idempotency: "best-effort-local",
44020
43921
  replayCursors: true,
44021
- description: `Local JSON files in ${dataDir22}; no SQLite, Postgres, S3, or AWS runtime is configured by this store.`
43922
+ description: `Local JSON files in ${dataDir3}; no SQLite, Postgres, S3, or AWS runtime is configured by this store.`
44022
43923
  };
44023
43924
  }
44024
43925
  function encodeLocalJsonEventCursor(offset, options = {}) {
@@ -44082,8 +43983,8 @@ function assertCursorFilter(name, cursorValue, optionValue) {
44082
43983
  function findEventByIdentity(events2, identity3) {
44083
43984
  return events2.find((event) => identity3.id !== undefined && event.id === identity3.id || identity3.dedupeKey !== undefined && event.dedupeKey === identity3.dedupeKey);
44084
43985
  }
44085
- async function getEventsStatus(dataDir22) {
44086
- const store = new JsonEventsStore(dataDir22);
43986
+ async function getEventsStatus(dataDir3) {
43987
+ const store = new JsonEventsStore(dataDir3);
44087
43988
  await store.init();
44088
43989
  const [channels, events2, deliveries] = await Promise.all([
44089
43990
  store.listChannels(),
@@ -44125,9 +44026,9 @@ async function getEventsStatus(dataDir22) {
44125
44026
  }
44126
44027
  };
44127
44028
  }
44128
- function statusFile(dataDir22, fileName, records) {
44129
- const path = join22(dataDir22, fileName);
44130
- return { path, exists: existsSync22(path), records };
44029
+ function statusFile(dataDir3, fileName, records) {
44030
+ const path = join20(dataDir3, fileName);
44031
+ return { path, exists: existsSync13(path), records };
44131
44032
  }
44132
44033
  var DEFAULT_SIGNATURE_TOLERANCE_MS = 5 * 60 * 1000;
44133
44034
  function buildSignatureBase(timestamp, body) {
@@ -44137,214 +44038,6 @@ function signPayload(secret, timestamp, body) {
44137
44038
  const digest4 = createHmac("sha256", secret).update(buildSignatureBase(timestamp, body)).digest("hex");
44138
44039
  return `sha256=${digest4}`;
44139
44040
  }
44140
- var DEFAULT_MAX_REDIRECTS = 5;
44141
- var IPV4_PRIVATE_RANGES = [
44142
- [0, 16777215],
44143
- [167772160, 184549375],
44144
- [1681915904, 1686110207],
44145
- [2130706432, 2147483647],
44146
- [2851995648, 2852061183],
44147
- [2886729728, 2887778303],
44148
- [3221225472, 3221225727],
44149
- [3221225984, 3221226239],
44150
- [3227017984, 3227018239],
44151
- [3232235520, 3232301055],
44152
- [3323068416, 3323199487],
44153
- [3325256704, 3325256959],
44154
- [3405803776, 3405804031],
44155
- [3758096384, 4294967295]
44156
- ];
44157
- var IPV6_SPECIAL_PREFIXES = [
44158
- { groups: [0, 0, 0, 0, 0, 0, 0, 0], bits: 128 },
44159
- { groups: [0, 0, 0, 0, 0, 0, 0, 1], bits: 128 },
44160
- { groups: [0, 0, 0, 0, 0, 65535, 0, 0], bits: 96 },
44161
- { groups: [100, 65435, 0, 0, 0, 0, 0, 0], bits: 96 },
44162
- { groups: [256, 0, 0, 0, 0, 0, 0, 0], bits: 64 },
44163
- { groups: [8193, 0, 0, 0, 0, 0, 0, 0], bits: 32 },
44164
- { groups: [8193, 2, 0, 0, 0, 0, 0, 0], bits: 48 },
44165
- { groups: [8193, 16, 0, 0, 0, 0, 0, 0], bits: 28 },
44166
- { groups: [8193, 3512, 0, 0, 0, 0, 0, 0], bits: 32 },
44167
- { groups: [8194, 0, 0, 0, 0, 0, 0, 0], bits: 16 },
44168
- { groups: [16383, 0, 0, 0, 0, 0, 0, 0], bits: 20 },
44169
- { groups: [64512, 0, 0, 0, 0, 0, 0, 0], bits: 7 },
44170
- { groups: [65152, 0, 0, 0, 0, 0, 0, 0], bits: 10 },
44171
- { groups: [65216, 0, 0, 0, 0, 0, 0, 0], bits: 10 },
44172
- { groups: [65280, 0, 0, 0, 0, 0, 0, 0], bits: 8 }
44173
- ];
44174
- function isPrivateAddress(address) {
44175
- const normalized = stripZoneId(address);
44176
- const version2 = isIP(normalized);
44177
- if (version2 === 4) {
44178
- const integer3 = ipv4ToInt(normalized);
44179
- if (integer3 === undefined)
44180
- return true;
44181
- return IPV4_PRIVATE_RANGES.some(([low, high]) => integer3 >= low && integer3 <= high);
44182
- }
44183
- if (version2 === 6) {
44184
- const groups = ipv6Groups(normalized);
44185
- if (!groups)
44186
- return true;
44187
- for (const prefix3 of IPV6_SPECIAL_PREFIXES) {
44188
- if (!ipv6MatchesPrefix(groups, prefix3.groups, prefix3.bits))
44189
- continue;
44190
- if (prefix3.bits === 96 && groups[5] === 65535) {
44191
- return isPrivateAddress(ipv4IntToString(groups[6] << 16 | groups[7]));
44192
- }
44193
- if (prefix3.bits === 16 && groups[0] === 8194) {
44194
- return isPrivateAddress(ipv4IntToString(groups[1] << 16 | groups[2]));
44195
- }
44196
- return true;
44197
- }
44198
- return false;
44199
- }
44200
- return true;
44201
- }
44202
- async function resolveWebhookTarget(url2, policy = {}) {
44203
- const hostname3 = normalizeHostname(url2.hostname);
44204
- const allowlist = (policy.allowPrivateHosts ?? []).map((entry) => normalizeHostname(entry.toLowerCase()));
44205
- if (allowlist.includes(hostname3)) {
44206
- const version22 = isIP(hostname3);
44207
- if (version22 === 4 || version22 === 6) {
44208
- return { hostname: hostname3, addresses: [hostname3] };
44209
- }
44210
- const lookup2 = policy.lookup ?? defaultTargetLookup;
44211
- let resolved2;
44212
- try {
44213
- resolved2 = await lookup2(hostname3);
44214
- } catch {
44215
- throw new Error(`Webhook target ${hostname3} could not be resolved`);
44216
- }
44217
- if (!Array.isArray(resolved2) || resolved2.length === 0) {
44218
- throw new Error(`Webhook target ${hostname3} resolved to no addresses`);
44219
- }
44220
- const addresses = resolved2.map((entry) => normalizeHostname(entry.address));
44221
- return { hostname: hostname3, addresses };
44222
- }
44223
- const version2 = isIP(hostname3);
44224
- if (version2 === 4 || version2 === 6) {
44225
- if (isPrivateAddress(hostname3)) {
44226
- throw new Error(`Webhook target ${hostname3} is a private or special-use address`);
44227
- }
44228
- return { hostname: hostname3, addresses: [hostname3] };
44229
- }
44230
- const lookup = policy.lookup ?? defaultTargetLookup;
44231
- let resolved;
44232
- try {
44233
- resolved = await lookup(hostname3);
44234
- } catch {
44235
- throw new Error(`Webhook target ${hostname3} could not be resolved`);
44236
- }
44237
- if (!Array.isArray(resolved) || resolved.length === 0) {
44238
- throw new Error(`Webhook target ${hostname3} resolved to no addresses`);
44239
- }
44240
- const allowed = [];
44241
- for (const entry of resolved) {
44242
- const address = normalizeHostname(entry.address);
44243
- if (isPrivateAddress(address)) {
44244
- if (allowlist.includes(address)) {
44245
- allowed.push(address);
44246
- continue;
44247
- }
44248
- throw new Error(`Webhook target ${hostname3} resolves to private or special-use address ${address}`);
44249
- }
44250
- allowed.push(address);
44251
- }
44252
- if (allowed.length === 0) {
44253
- throw new Error(`Webhook target ${hostname3} resolved to no public addresses`);
44254
- }
44255
- return { hostname: hostname3, addresses: allowed };
44256
- }
44257
- function normalizeMaxRedirects(value) {
44258
- if (value === undefined)
44259
- return DEFAULT_MAX_REDIRECTS;
44260
- if (!Number.isInteger(value) || value < 0)
44261
- throw new Error("webhookTargetPolicy.maxRedirects must be a non-negative integer");
44262
- return value;
44263
- }
44264
- var defaultTargetLookup = async (hostname3) => {
44265
- return dnsLookup(hostname3, { all: true, verbatim: false });
44266
- };
44267
- function normalizeHostname(hostname3) {
44268
- const lower = hostname3.toLowerCase();
44269
- if (lower.startsWith("[") && lower.endsWith("]"))
44270
- return lower.slice(1, -1);
44271
- return lower;
44272
- }
44273
- function stripZoneId(address) {
44274
- const percent = address.indexOf("%");
44275
- return percent === -1 ? address : address.slice(0, percent);
44276
- }
44277
- function ipv4ToInt(address) {
44278
- const parts = address.split(".");
44279
- if (parts.length !== 4)
44280
- return;
44281
- let value = 0;
44282
- for (const part of parts) {
44283
- if (!/^\d{1,3}$/.test(part))
44284
- return;
44285
- const octet = Number(part);
44286
- if (octet > 255)
44287
- return;
44288
- value = value << 8 | octet;
44289
- }
44290
- return value >>> 0;
44291
- }
44292
- function ipv4IntToString(integer3) {
44293
- return [
44294
- integer3 >>> 24 & 255,
44295
- integer3 >>> 16 & 255,
44296
- integer3 >>> 8 & 255,
44297
- integer3 & 255
44298
- ].join(".");
44299
- }
44300
- function ipv6Groups(address) {
44301
- const raw = stripZoneId(address);
44302
- const doubleColon = raw.indexOf("::");
44303
- const headText = doubleColon === -1 ? raw : raw.slice(0, doubleColon);
44304
- const tailText = doubleColon === -1 ? "" : raw.slice(doubleColon + 2);
44305
- const parseGroups = (text3) => {
44306
- if (text3 === "")
44307
- return [];
44308
- const out = [];
44309
- for (const part of text3.split(":")) {
44310
- if (part.includes(".")) {
44311
- const v4 = ipv4ToInt(part);
44312
- if (v4 === undefined)
44313
- return;
44314
- out.push(v4 >>> 16 & 65535, v4 & 65535);
44315
- } else {
44316
- if (!/^[0-9a-fA-F]{1,4}$/.test(part))
44317
- return;
44318
- out.push(parseInt(part, 16));
44319
- }
44320
- }
44321
- return out;
44322
- };
44323
- const head = parseGroups(headText);
44324
- if (!head)
44325
- return;
44326
- const tail = parseGroups(tailText);
44327
- if (!tail)
44328
- return;
44329
- const total = head.length + tail.length;
44330
- if (doubleColon === -1) {
44331
- return total === 8 ? head : undefined;
44332
- }
44333
- if (total >= 8)
44334
- return;
44335
- return [...head, ...new Array(8 - total).fill(0), ...tail];
44336
- }
44337
- function ipv6MatchesPrefix(groups, prefixGroups, prefixBits) {
44338
- let remaining = prefixBits;
44339
- for (let index = 0;index < prefixGroups.length && remaining > 0; index += 1) {
44340
- const take = Math.min(16, remaining);
44341
- const mask = 65535 << 16 - take & 65535;
44342
- if ((groups[index] & mask) !== (prefixGroups[index] & mask))
44343
- return false;
44344
- remaining -= take;
44345
- }
44346
- return true;
44347
- }
44348
44041
  function now() {
44349
44042
  return new Date().toISOString();
44350
44043
  }
@@ -44375,18 +44068,9 @@ function buildWebhookRequest(event, channel, options = {}) {
44375
44068
  }
44376
44069
  return { body, headers };
44377
44070
  }
44378
- function normalizeWebhookUrl(raw) {
44379
- const url2 = new URL(raw);
44380
- if (url2.username !== "" || url2.password !== "") {
44381
- url2.username = "";
44382
- url2.password = "";
44383
- }
44384
- return url2.toString();
44385
- }
44386
44071
  async function dispatchWebhook(event, channel, options = {}) {
44387
44072
  if (!channel.webhook)
44388
44073
  throw new Error(`Channel ${channel.id} has no webhook config`);
44389
- const webhookUrl = normalizeWebhookUrl(channel.webhook.url);
44390
44074
  const startedAt = now();
44391
44075
  let secret = channel.webhook.secret;
44392
44076
  if (channel.webhook.secretRef) {
@@ -44403,14 +44087,10 @@ async function dispatchWebhook(event, channel, options = {}) {
44403
44087
  }
44404
44088
  const timestamp = (options.now?.() ?? new Date).toISOString();
44405
44089
  const { body, headers } = buildWebhookRequest(event, channel, { secret, timestamp });
44406
- const validateTargets = options.webhookTargetPolicy !== undefined || options.fetchImpl === undefined;
44407
- if (validateTargets) {
44408
- return dispatchValidatedWebhook(event, channel, { body, headers, startedAt, options });
44409
- }
44410
44090
  const controller = new AbortController;
44411
44091
  const timeout = setTimeout(() => controller.abort(), channel.webhook.timeoutMs ?? 15000);
44412
44092
  try {
44413
- const response = await (options.fetchImpl ?? fetch)(webhookUrl, {
44093
+ const response = await (options.fetchImpl ?? fetch)(channel.webhook.url, {
44414
44094
  method: "POST",
44415
44095
  headers,
44416
44096
  body,
@@ -44438,130 +44118,6 @@ async function dispatchWebhook(event, channel, options = {}) {
44438
44118
  clearTimeout(timeout);
44439
44119
  }
44440
44120
  }
44441
- function isRedirectStatus(status) {
44442
- return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
44443
- }
44444
- function redirectKeepsBody(status) {
44445
- return status === 307 || status === 308;
44446
- }
44447
- async function pinnedNativeRequest(target, addresses, method, headers, body, signal, tls) {
44448
- const isHttps = target.protocol === "https:";
44449
- if (!isHttps && target.protocol !== "http:") {
44450
- throw new Error(`Webhook target uses unsupported protocol ${target.protocol}`);
44451
- }
44452
- const defaultPort = isHttps ? 443 : 80;
44453
- const port = target.port ? Number(target.port) : defaultPort;
44454
- const requestOptions = {
44455
- hostname: target.hostname,
44456
- port,
44457
- path: `${target.pathname}${target.search}`,
44458
- method,
44459
- headers,
44460
- ...tls?.ca ? { ca: tls.ca } : {},
44461
- lookup: (hostname3, _options, callback) => {
44462
- const entries = addresses.map((address) => ({
44463
- address,
44464
- family: address.includes(":") ? 6 : 4
44465
- }));
44466
- callback(null, entries);
44467
- }
44468
- };
44469
- return new Promise((resolve23, reject) => {
44470
- const request = isHttps ? nodeHttpsRequest(requestOptions, onResponse) : nodeHttpRequest(requestOptions, onResponse);
44471
- const onAbort = () => {
44472
- const error61 = new Error("The operation was aborted.");
44473
- error61.name = "AbortError";
44474
- request.destroy(error61);
44475
- };
44476
- if (signal.aborted)
44477
- onAbort();
44478
- else
44479
- signal.addEventListener("abort", onAbort, { once: true });
44480
- request.on("error", reject);
44481
- if (body !== undefined)
44482
- request.write(body);
44483
- request.end();
44484
- function onResponse(response) {
44485
- const chunks = [];
44486
- response.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
44487
- response.on("error", reject);
44488
- response.on("end", () => {
44489
- const headersRecord = {};
44490
- for (const [name, value] of Object.entries(response.headers)) {
44491
- if (typeof value === "string")
44492
- headersRecord[name] = value;
44493
- else if (Array.isArray(value))
44494
- headersRecord[name] = value.join(", ");
44495
- }
44496
- resolve23(new Response(Buffer.concat(chunks), { status: response.statusCode ?? 200, headers: headersRecord }));
44497
- });
44498
- }
44499
- });
44500
- }
44501
- async function dispatchValidatedWebhook(event, channel, input2) {
44502
- const { body, headers, startedAt, options } = input2;
44503
- const webhook = channel.webhook;
44504
- if (!webhook)
44505
- throw new Error(`Channel ${channel.id} has no webhook config`);
44506
- const policy = options.webhookTargetPolicy ?? {};
44507
- const maxRedirects = normalizeMaxRedirects(policy.maxRedirects);
44508
- const controller = new AbortController;
44509
- const timeout = setTimeout(() => controller.abort(), webhook.timeoutMs ?? 15000);
44510
- try {
44511
- let target = new URL(normalizeWebhookUrl(webhook.url));
44512
- let requestHeaders = headers;
44513
- let method = "POST";
44514
- let requestBody = body;
44515
- let redirectsFollowed = 0;
44516
- for (;; ) {
44517
- const resolved = await resolveWebhookTarget(target, policy).catch((error61) => {
44518
- throw new Error(`Webhook target rejected by SSRF guard: ${error61.message}`);
44519
- });
44520
- const response = options.fetchImpl ? await options.fetchImpl(target, {
44521
- method,
44522
- headers: requestHeaders,
44523
- body: requestBody,
44524
- signal: controller.signal,
44525
- redirect: "manual"
44526
- }) : await pinnedNativeRequest(target, resolved.addresses, method, requestHeaders, requestBody, controller.signal, options.tls);
44527
- const location = response.headers.get("location");
44528
- if (isRedirectStatus(response.status) && location) {
44529
- if (redirectsFollowed >= maxRedirects) {
44530
- return failedAttempt(startedAt, `Webhook target exceeded ${maxRedirects} redirects`);
44531
- }
44532
- redirectsFollowed += 1;
44533
- const next = new URL(location, target);
44534
- target = next;
44535
- if (!redirectKeepsBody(response.status)) {
44536
- method = "GET";
44537
- requestBody = undefined;
44538
- requestHeaders = Object.fromEntries(Object.entries(requestHeaders).filter(([name]) => name.toLowerCase() !== "content-type" && name.toLowerCase() !== "content-length"));
44539
- }
44540
- continue;
44541
- }
44542
- const responseBody = truncate(await response.text());
44543
- return {
44544
- attempt: 1,
44545
- status: response.ok ? "success" : "failed",
44546
- startedAt,
44547
- completedAt: now(),
44548
- responseStatus: response.status,
44549
- responseBody,
44550
- error: response.ok ? undefined : `Webhook returned HTTP ${response.status}`
44551
- };
44552
- }
44553
- } catch (error61) {
44554
- return {
44555
- attempt: 1,
44556
- status: "failed",
44557
- startedAt,
44558
- completedAt: now(),
44559
- error: error61 instanceof Error ? error61.message : String(error61)
44560
- };
44561
- } finally {
44562
- clearTimeout(timeout);
44563
- }
44564
- }
44565
44121
  function failedAttempt(startedAt, error61) {
44566
44122
  return {
44567
44123
  attempt: 1,
@@ -44590,7 +44146,7 @@ async function dispatchCommand(event, channel) {
44590
44146
  HASNA_EVENT_SCHEMA_VERSION: event.schemaVersion,
44591
44147
  HASNA_EVENT_JSON: eventJson
44592
44148
  };
44593
- return new Promise((resolve23) => {
44149
+ return new Promise((resolve16) => {
44594
44150
  const child = spawn3(channel.command.command, channel.command.args ?? [], {
44595
44151
  cwd: channel.command.cwd,
44596
44152
  env,
@@ -44608,7 +44164,7 @@ async function dispatchCommand(event, channel) {
44608
44164
  });
44609
44165
  child.on("error", (error61) => {
44610
44166
  clearTimeout(timeout);
44611
- resolve23({
44167
+ resolve16({
44612
44168
  attempt: 1,
44613
44169
  status: "failed",
44614
44170
  startedAt,
@@ -44621,7 +44177,7 @@ async function dispatchCommand(event, channel) {
44621
44177
  child.on("close", (code2, signal) => {
44622
44178
  clearTimeout(timeout);
44623
44179
  const success2 = code2 === 0;
44624
- resolve23({
44180
+ resolve16({
44625
44181
  attempt: 1,
44626
44182
  status: success2 ? "success" : "failed",
44627
44183
  startedAt,
@@ -44743,22 +44299,6 @@ function setPath(input2, path, replacement) {
44743
44299
  if (last && last in cursor)
44744
44300
  cursor[last] = replacement;
44745
44301
  }
44746
- var MAX_PACKAGE_BYTES2 = 1024 * 1024;
44747
- var MAX_CREDENTIAL_FILE_BYTES2 = 64 * 1024;
44748
- var INSPECT_CUSTOM2 = Symbol.for("nodejs.util.inspect.custom");
44749
- var CREDENTIAL_SEAL2 = Symbol.for("hasna:contracts:sealedCredential");
44750
- var AMBIENT_ENVIRONMENT2 = Symbol.for("hasna:contracts:ambientClientEnvironment");
44751
- var requireSecretsSdk2 = createRequire2(import.meta.url);
44752
- var IDEMPOTENT_METHODS2 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
44753
- var AUTHORITY_OVERRIDE_HEADERS2 = new Set([
44754
- "host",
44755
- ":authority",
44756
- "forwarded",
44757
- "x-forwarded-host",
44758
- "x-original-host"
44759
- ]);
44760
- var MAX_ENVELOPE_BYTES = 256 * 1024;
44761
- var MAX_REQUEST_BYTES = MAX_ENVELOPE_BYTES * 2 + 8192;
44762
44302
  function createEvent(input2) {
44763
44303
  return {
44764
44304
  id: input2.id ?? randomUUID22(),
@@ -44787,9 +44327,7 @@ class EventsClient {
44787
44327
  this.transportOptions = {
44788
44328
  fetchImpl: options.fetchImpl,
44789
44329
  secretResolver: options.secretResolver,
44790
- now: options.now,
44791
- tls: options.tls,
44792
- webhookTargetPolicy: options.webhookTargetPolicy
44330
+ now: options.now
44793
44331
  };
44794
44332
  this.catalog = options.catalog ?? defaultEventTypeCatalog;
44795
44333
  this.validateCatalogTypes = options.validateCatalogTypes ?? false;
@@ -45076,13 +44614,6 @@ function parseMatcherExpression(value, label) {
45076
44614
  negated: false
45077
44615
  };
45078
44616
  }
45079
- function webhookTargetPolicyFromEnv() {
45080
- const value = process.env.HASNA_EVENTS_ALLOW_PRIVATE_WEBHOOK_TARGETS;
45081
- if (!value)
45082
- return;
45083
- const hosts = value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
45084
- return hosts.length > 0 ? { allowPrivateHosts: hosts } : undefined;
45085
- }
45086
44617
  var DEFAULT_EVENT_LIST_LIMIT = 100;
45087
44618
  function parseJsonObject(value, fallback) {
45088
44619
  if (!value)
@@ -45108,7 +44639,7 @@ function parseHeaders(values) {
45108
44639
  function createClient(options) {
45109
44640
  if (options.createClient)
45110
44641
  return options.createClient();
45111
- return new EventsClient({ store: new JsonEventsStore(options.dataDir), webhookTargetPolicy: webhookTargetPolicyFromEnv() });
44642
+ return new EventsClient({ store: new JsonEventsStore(options.dataDir) });
45112
44643
  }
45113
44644
  function print(value, json2, text3) {
45114
44645
  if (json2)
@@ -45189,8 +44720,6 @@ function registerChannelCommands(program2, options) {
45189
44720
  metadata: parseJsonObject(actionOptions.metadata, {})
45190
44721
  }, { honorFilters: actionOptions.honorFilters });
45191
44722
  print(result, json2, `${result.status}: ${result.channelId}`);
45192
- if (result.status === "failed")
45193
- process.exitCode = 1;
45194
44723
  } catch (error61) {
45195
44724
  fail(error61, json2);
45196
44725
  }
@@ -45283,7 +44812,7 @@ function replaySummary(events2, deliveries, nextCursor) {
45283
44812
  // src/cli/index.tsx
45284
44813
  import { render } from "ink";
45285
44814
 
45286
- // ../../node_modules/.bun/commander@12.1.0/node_modules/commander/esm.mjs
44815
+ // node_modules/commander/esm.mjs
45287
44816
  var import__ = __toESM(require_commander(), 1);
45288
44817
  var {
45289
44818
  program: program2,
@@ -45302,18 +44831,18 @@ var {
45302
44831
  // src/cli/index.tsx
45303
44832
  import chalk2 from "chalk";
45304
44833
  import { existsSync as existsSync18, readFileSync as readFileSync27, rmSync as rmSync6 } from "fs";
45305
- import { join as join36, dirname as dirname28 } from "path";
44834
+ import { join as join35, dirname as dirname28 } from "path";
45306
44835
  import { fileURLToPath as fileURLToPath6 } from "url";
45307
44836
 
45308
44837
  // src/cli/components/App.tsx
45309
44838
  import { useState as useState7 } from "react";
45310
44839
  import { Box as Box8, Text as Text10, useApp, useInput as useInput5 } from "ink";
45311
44840
 
45312
- // ../../node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/Indicator.js
44841
+ // node_modules/ink-select-input/build/Indicator.js
45313
44842
  import React from "react";
45314
44843
  import { Box, Text } from "ink";
45315
44844
 
45316
- // ../../node_modules/.bun/is-unicode-supported@2.1.0/node_modules/is-unicode-supported/index.js
44845
+ // node_modules/is-unicode-supported/index.js
45317
44846
  import process3 from "process";
45318
44847
  function isUnicodeSupported() {
45319
44848
  const { env } = process3;
@@ -45324,7 +44853,7 @@ function isUnicodeSupported() {
45324
44853
  return Boolean(env.WT_SESSION) || Boolean(env.TERMINUS_SUBLIME) || env.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
45325
44854
  }
45326
44855
 
45327
- // ../../node_modules/.bun/figures@6.1.0/node_modules/figures/index.js
44856
+ // node_modules/figures/index.js
45328
44857
  var common2 = {
45329
44858
  circleQuestionMark: "(?)",
45330
44859
  questionMarkPrefix: "(?)",
@@ -45600,23 +45129,23 @@ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
45600
45129
  var figures_default = figures;
45601
45130
  var replacements = Object.entries(specialMainSymbols);
45602
45131
 
45603
- // ../../node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/Indicator.js
45132
+ // node_modules/ink-select-input/build/Indicator.js
45604
45133
  function Indicator({ isSelected = false }) {
45605
45134
  return React.createElement(Box, { marginRight: 1 }, isSelected ? React.createElement(Text, { color: "blue" }, figures_default.pointer) : React.createElement(Text, null, " "));
45606
45135
  }
45607
45136
  var Indicator_default = Indicator;
45608
- // ../../node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/Item.js
45137
+ // node_modules/ink-select-input/build/Item.js
45609
45138
  import * as React2 from "react";
45610
45139
  import { Text as Text2 } from "ink";
45611
45140
  function Item({ isSelected = false, label }) {
45612
45141
  return React2.createElement(Text2, { color: isSelected ? "blue" : undefined }, label);
45613
45142
  }
45614
45143
  var Item_default = Item;
45615
- // ../../node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/SelectInput.js
45144
+ // node_modules/ink-select-input/build/SelectInput.js
45616
45145
  import { isDeepStrictEqual } from "util";
45617
45146
  import React3, { useState, useEffect, useRef, useCallback } from "react";
45618
45147
 
45619
- // ../../node_modules/.bun/to-rotated@1.0.0/node_modules/to-rotated/index.js
45148
+ // node_modules/to-rotated/index.js
45620
45149
  function toRotated(array3, steps) {
45621
45150
  if (!Array.isArray(array3)) {
45622
45151
  throw new TypeError(`Expected an array, got \`${typeof array3}\`.`);
@@ -45638,7 +45167,7 @@ function toRotated(array3, steps) {
45638
45167
  ];
45639
45168
  }
45640
45169
 
45641
- // ../../node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/SelectInput.js
45170
+ // node_modules/ink-select-input/build/SelectInput.js
45642
45171
  import { Box as Box2, useInput } from "ink";
45643
45172
  function SelectInput({ items = [], isFocused = true, initialIndex = 0, indicatorComponent = Indicator_default, itemComponent = Item_default, limit: customLimit, onSelect, onHighlight }) {
45644
45173
  const hasLimit = typeof customLimit === "number" && items.length > customLimit;
@@ -45934,7 +45463,7 @@ function HookSelect({
45934
45463
  import { useState as useState4, useEffect as useEffect3 } from "react";
45935
45464
  import { Box as Box6, Text as Text7, useInput as useInput4 } from "ink";
45936
45465
 
45937
- // ../../node_modules/.bun/ink-text-input@6.0.0+fa875fef9f949ebd/node_modules/ink-text-input/build/index.js
45466
+ // node_modules/ink-text-input/build/index.js
45938
45467
  import React5, { useState as useState3, useEffect as useEffect2 } from "react";
45939
45468
  import { Text as Text6, useInput as useInput3 } from "ink";
45940
45469
  import chalk from "chalk";
@@ -46112,7 +45641,7 @@ function SearchView({
46112
45641
  import { useState as useState6, useEffect as useEffect5 } from "react";
46113
45642
  import { Box as Box7, Text as Text9 } from "ink";
46114
45643
 
46115
- // ../../node_modules/.bun/ink-spinner@5.0.0+fa875fef9f949ebd/node_modules/ink-spinner/build/index.js
45644
+ // node_modules/ink-spinner/build/index.js
46116
45645
  var import_cli_spinners = __toESM(require_cli_spinners(), 1);
46117
45646
  import React7, { useState as useState5, useEffect as useEffect4 } from "react";
46118
45647
  import { Text as Text8 } from "ink";
@@ -46479,10 +46008,10 @@ init_native_safety();
46479
46008
 
46480
46009
  // src/lib/sumi-binding.ts
46481
46010
  import { homedir as homedir14 } from "os";
46482
- import { join as join27, sep as sep3 } from "path";
46011
+ import { join as join24, sep as sep3 } from "path";
46483
46012
 
46484
46013
  // hooks/hook-trash-guard/src/binary.ts
46485
- import { dirname as dirname21, isAbsolute as isAbsolute20, join as join24, resolve as resolve21 } from "path";
46014
+ import { dirname as dirname21, isAbsolute as isAbsolute20, join as join22, resolve as resolve20 } from "path";
46486
46015
  import { accessSync, closeSync as closeSync19, constants as constants18, fstatSync as fstatSync18, lstatSync as lstatSync23, openSync as openSync19, readFileSync as readFileSync17, readlinkSync as readlinkSync3, readSync as readSync3, realpathSync as realpathSync11, statSync } from "fs";
46487
46016
  import { spawnSync } from "child_process";
46488
46017
  function trustedOwner(uid2) {
@@ -46504,7 +46033,7 @@ function safeExecutableFile(path, systemBinAlias = false) {
46504
46033
  parent = dirname21(parent);
46505
46034
  continue;
46506
46035
  }
46507
- const next = join24(parent, part), info2 = lstatSync23(next);
46036
+ const next = join22(parent, part), info2 = lstatSync23(next);
46508
46037
  if (systemBinAlias && next === "/bin" && info2.isSymbolicLink() && info2.uid === 0) {
46509
46038
  const target = realpathSync11(next);
46510
46039
  if (!safeBinaryDirectory(target))
@@ -46516,7 +46045,7 @@ function safeExecutableFile(path, systemBinAlias = false) {
46516
46045
  return false;
46517
46046
  parent = next;
46518
46047
  }
46519
- const candidate = join24(parent, name), info = lstatSync23(candidate);
46048
+ const candidate = join22(parent, name), info = lstatSync23(candidate);
46520
46049
  if (!trustedOwner(info.uid))
46521
46050
  return false;
46522
46051
  if (info.isSymbolicLink()) {
@@ -46529,9 +46058,9 @@ function safeExecutableFile(path, systemBinAlias = false) {
46529
46058
  return false;
46530
46059
  }
46531
46060
  function safeInterpreterSearchDirectory(path) {
46532
- if (!isAbsolute20(path) || resolve21(path) !== (path.replace(/\/+$/, "") || "/"))
46061
+ if (!isAbsolute20(path) || resolve20(path) !== (path.replace(/\/+$/, "") || "/"))
46533
46062
  return false;
46534
- for (let cursor = resolve21(path);; cursor = dirname21(cursor)) {
46063
+ for (let cursor = resolve20(path);; cursor = dirname21(cursor)) {
46535
46064
  try {
46536
46065
  lstatSync23(cursor);
46537
46066
  return safeBinaryDirectory(cursor);
@@ -46563,7 +46092,7 @@ function safeScriptInterpreter(executable2, pathValue) {
46563
46092
  for (const dir of pathValue.split(":").slice(0, 64)) {
46564
46093
  if (!safeInterpreterSearchDirectory(dir))
46565
46094
  return false;
46566
- const interpreter = resolve21(dir, "bun");
46095
+ const interpreter = resolve20(dir, "bun");
46567
46096
  try {
46568
46097
  if (!statSync(interpreter).isFile())
46569
46098
  continue;
@@ -46598,7 +46127,7 @@ function inspectTrashBinary(env = process.env) {
46598
46127
  for (const dir of pathValue.split(":").slice(0, 64)) {
46599
46128
  if (!isAbsolute20(dir) || Date.now() >= deadline)
46600
46129
  continue;
46601
- const candidate = resolve21(dir, "trash");
46130
+ const candidate = resolve20(dir, "trash");
46602
46131
  try {
46603
46132
  const stat2 = statSync(candidate);
46604
46133
  if (!stat2.isFile() || !trustedOwner(stat2.uid) || (stat2.mode & 73) === 0 || (stat2.mode & 18) !== 0) {
@@ -46606,7 +46135,7 @@ function inspectTrashBinary(env = process.env) {
46606
46135
  continue;
46607
46136
  }
46608
46137
  const executable2 = realpathSync11(candidate);
46609
- if (!safeBinaryDirectory(resolve21(dir)) || !safeBinaryDirectory(dirname21(executable2))) {
46138
+ if (!safeBinaryDirectory(resolve20(dir)) || !safeBinaryDirectory(dirname21(executable2))) {
46610
46139
  reject("unsafe_directory");
46611
46140
  continue;
46612
46141
  }
@@ -46614,15 +46143,15 @@ function inspectTrashBinary(env = process.env) {
46614
46143
  reject("unsafe_directory");
46615
46144
  continue;
46616
46145
  }
46617
- const packageRoot = resolve21(dirname21(executable2), "../..");
46618
- const manifestPath = join24(packageRoot, "package.json");
46146
+ const packageRoot = resolve20(dirname21(executable2), "../..");
46147
+ const manifestPath = join22(packageRoot, "package.json");
46619
46148
  const manifestStat = statSync(manifestPath);
46620
46149
  if (!manifestStat.isFile() || !trustedOwner(manifestStat.uid) || manifestStat.size > 16384 || (manifestStat.mode & 18) !== 0 || lstatSync23(manifestPath).isSymbolicLink()) {
46621
46150
  reject("unsafe_manifest");
46622
46151
  continue;
46623
46152
  }
46624
46153
  const manifest = JSON.parse(readFileSync17(manifestPath, "utf8"));
46625
- if (manifest.name !== "@hasna/trash" || typeof manifest.version !== "string" || typeof manifest.bin?.trash !== "string" || realpathSync11(resolve21(packageRoot, manifest.bin.trash)) !== executable2) {
46154
+ if (manifest.name !== "@hasna/trash" || typeof manifest.version !== "string" || typeof manifest.bin?.trash !== "string" || realpathSync11(resolve20(packageRoot, manifest.bin.trash)) !== executable2) {
46626
46155
  reject("unrecognized_package");
46627
46156
  continue;
46628
46157
  }
@@ -46635,14 +46164,19 @@ function inspectTrashBinary(env = process.env) {
46635
46164
  reject("unsafe_interpreter");
46636
46165
  continue;
46637
46166
  }
46167
+ const remaining = deadline - Date.now();
46168
+ if (remaining <= 0) {
46169
+ reject("identity_failed");
46170
+ break;
46171
+ }
46638
46172
  const probe = spawnSync(candidate, ["--identity"], {
46639
46173
  encoding: "utf8",
46640
- timeout: Math.max(1, Math.min(500, deadline - Date.now())),
46174
+ timeout: remaining,
46641
46175
  maxBuffer: 2048,
46642
46176
  env: { PATH: pathValue },
46643
46177
  stdio: ["ignore", "pipe", "pipe"]
46644
46178
  });
46645
- if (probe.error || probe.status !== 0) {
46179
+ if (probe.error || probe.status !== 0 || Date.now() >= deadline) {
46646
46180
  reject("identity_failed");
46647
46181
  continue;
46648
46182
  }
@@ -46662,7 +46196,7 @@ function failure(code2, reason) {
46662
46196
  return { ok: false, target: "sumi", code: code2, ...reason ? { reason: reason.slice(0, 300) } : {} };
46663
46197
  }
46664
46198
  function nativeSafetyBindingDurable(worker, home) {
46665
- return !(worker.startsWith(join27(home, ".bun") + sep3) || worker.includes(`${sep3}node_modules${sep3}.bun${sep3}`));
46199
+ return !(worker.startsWith(join24(home, ".bun") + sep3) || worker.includes(`${sep3}node_modules${sep3}.bun${sep3}`));
46666
46200
  }
46667
46201
  async function provisionSumiSafetyBinding(options = {}) {
46668
46202
  const home = options.home ?? homedir14();
@@ -46737,7 +46271,7 @@ init_transport2();
46737
46271
  init_db();
46738
46272
  import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
46739
46273
  var __dirname4 = dirname28(fileURLToPath6(import.meta.url));
46740
- var pkgPath = existsSync18(join36(__dirname4, "..", "package.json")) ? join36(__dirname4, "..", "package.json") : join36(__dirname4, "..", "..", "package.json");
46274
+ var pkgPath = existsSync18(join35(__dirname4, "..", "package.json")) ? join35(__dirname4, "..", "package.json") : join35(__dirname4, "..", "..", "package.json");
46741
46275
  var pkg2 = JSON.parse(readFileSync27(pkgPath, "utf-8"));
46742
46276
  var program3 = new Command;
46743
46277
  function resolveScope(options) {
@@ -46970,7 +46504,7 @@ program3.command("init").description("Register a new agent profile with a unique
46970
46504
  if (profile.name) {
46971
46505
  console.log(` ${chalk2.dim("Name:")} ${profile.name}`);
46972
46506
  }
46973
- console.log(` ${chalk2.dim("Profile:")} ${join36(getProfilesDir(), `${profile.agent_id}.json`)}`);
46507
+ console.log(` ${chalk2.dim("Profile:")} ${join35(getProfilesDir(), `${profile.agent_id}.json`)}`);
46974
46508
  console.log();
46975
46509
  console.log(chalk2.dim(" Install hooks with this profile:"));
46976
46510
  console.log(` hooks install gitguard --profile ${profile.agent_id}`);
@@ -47625,7 +47159,7 @@ program3.command("doctor").option("-g, --global", "Check global settings", false
47625
47159
  continue;
47626
47160
  }
47627
47161
  const hookDir = getHookPath(name);
47628
- const hookScript = join36(hookDir, "src", "hook.ts");
47162
+ const hookScript = join35(hookDir, "src", "hook.ts");
47629
47163
  if (!existsSync18(hookScript)) {
47630
47164
  issues.push({ hook: name, issue: "Missing src/hook.ts in package", severity: "error" });
47631
47165
  hookHealthy = false;
@@ -47836,7 +47370,7 @@ program3.command("docs").argument("[hook]", "Hook name (shows general docs if om
47836
47370
  return;
47837
47371
  }
47838
47372
  const hookPath = getHookPath(hook);
47839
- const readmePath = join36(hookPath, "README.md");
47373
+ const readmePath = join35(hookPath, "README.md");
47840
47374
  let readme = "";
47841
47375
  if (existsSync18(readmePath)) {
47842
47376
  readme = readFileSync27(readmePath, "utf-8");
@@ -48634,7 +48168,7 @@ safety.command("verify").requiredOption("--target <target>", "sumi, codex or cla
48634
48168
  throw new ClaudeSafetyError("settings_invalid");
48635
48169
  console.log(JSON.stringify(await verifyClaudeSafetyConfiguration({
48636
48170
  cwd: options.cwd,
48637
- ...process.env.CLAUDE_CONFIG_DIR ? { userSettingsPath: resolve23(process.env.CLAUDE_CONFIG_DIR, "settings.json") } : {}
48171
+ ...process.env.CLAUDE_CONFIG_DIR ? { userSettingsPath: resolve21(process.env.CLAUDE_CONFIG_DIR, "settings.json") } : {}
48638
48172
  })));
48639
48173
  } catch (error61) {
48640
48174
  console.log(JSON.stringify({ ok: false, target: "claude", code: error61 instanceof ClaudeSafetyError ? error61.code : "settings_invalid", nativeAdoptionVerified: false }));