@hasna/hooks 0.11.1 → 0.11.2

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/@hasna/skills/dist/index.js
2519
+ // ../../../../../../../../.bun/install/cache/@hasna/skills@0.9.17@@@1/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";
@@ -35248,7 +35248,7 @@ var init_codex_safety_check = __esm(() => {
35248
35248
  init_native_safety();
35249
35249
  init_native_readiness_command();
35250
35250
  init_native_safety2();
35251
- versions = new Set(["codex-cli 0.153.0", "codex-cli 0.154.0", "codex-cli 0.155.0", "codex-cli 0.155.1", "codex-cli 0.156.1"]);
35251
+ versions = new Set(["codex-cli 0.153.0", "codex-cli 0.154.0", "codex-cli 0.155.0", "codex-cli 0.155.1", "codex-cli 0.156.1", "codex-cli 0.157.0", "codex-cli 0.157.1"]);
35252
35252
  CodexSafetyError = class CodexSafetyError extends Error {
35253
35253
  code;
35254
35254
  constructor(code2) {
@@ -35489,7 +35489,7 @@ var init_codex_safety_trust = __esm(() => {
35489
35489
  };
35490
35490
  });
35491
35491
 
35492
- // node_modules/commander/lib/error.js
35492
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/commander@12.1.0/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/commander/lib/argument.js
35516
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/commander@12.1.0/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/commander/lib/help.js
35595
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/commander@12.1.0/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/commander/lib/option.js
35844
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/commander@12.1.0/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/commander/lib/suggestSimilar.js
35995
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/commander@12.1.0/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/commander/lib/command.js
36068
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/commander@12.1.0/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/commander/index.js
37311
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/commander@12.1.0/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/cli-spinners/spinners.json
37331
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/cli-spinners@2.9.2/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/cli-spinners/index.js
38957
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/cli-spinners@2.9.2/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 join27 } from "path";
39038
+ import { join as join29 } from "path";
39039
39039
  function getProfilesDir() {
39040
- const newDir = join27(getEffectiveDataRoot(), "profiles");
39041
- const oldDir = join27(getHomeDir(), ".hooks", "profiles");
39040
+ const newDir = join29(getEffectiveDataRoot(), "profiles");
39041
+ const oldDir = join29(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 join27(getProfilesDir(), `${id}.json`);
39055
+ return join29(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(join27(dir, file2), "utf-8");
39097
+ const content = readFileSync19(join29(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/@hasna/contracts/dist/client/transport.js
39142
- import { isIP } from "net";
39141
+ // ../../../../codex0157-source-repair/isolated-build/repo/apps/hooks/node_modules/@hasna/contracts/dist/client/transport.js
39142
+ import { isIP as isIP2 } 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 createRequire2 } from "module";
39148
+ import { createRequire as createRequire3 } 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 join29, relative as relative5, sep as sep6 } from "path";
39152
+ import { basename as basename9, dirname as dirname22, join as join30, 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(join29(root, "package.json"), O_RDONLY | O_NOFOLLOW | O_NONBLOCK);
39227
+ const fd = openSync20(join30(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_BYTES2)
39231
+ if (!stat2.isFile() || stat2.size > MAX_PACKAGE_BYTES3)
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(join29(root, ...parts));
39247
+ const file2 = realpathSync12(join30(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 = join29(directory2, "node_modules", PACKAGE);
39258
+ const candidate = join30(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_BYTES2)
39378
+ if (before.size > MAX_CREDENTIAL_FILE_BYTES3)
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_CUSTOM2, {
39470
+ Object.defineProperty(sealed, INSPECT_CUSTOM3, {
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_SEAL2, {
39476
+ Object.defineProperty(sealed, CREDENTIAL_SEAL3, {
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_ENVIRONMENT2] === true;
39507
+ return env === process.env || env[AMBIENT_ENVIRONMENT3] === 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_ENVIRONMENT2, {
39601
+ Object.defineProperty(snapshot2, AMBIENT_ENVIRONMENT3, {
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 = requireSecretsSdk2(fileURLToPath22(sdkUrl));
39774
+ secretsSdk = requireSecretsSdk3(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 (isIP(rawHostname.slice(1, -1)) !== 6) {
39858
+ if (isIP2(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 = isIP(rawHostname);
39874
+ const ipVersion = isIP2(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_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;
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;
40011
40011
  var init_transport = __esm(() => {
40012
- MAX_PACKAGE_BYTES2 = 1024 * 1024;
40012
+ MAX_PACKAGE_BYTES3 = 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_BYTES2 = 64 * 1024;
40031
+ MAX_CREDENTIAL_FILE_BYTES3 = 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_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);
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);
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_METHODS2 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
40054
- AUTHORITY_OVERRIDE_HEADERS2 = new Set([
40053
+ IDEMPOTENT_METHODS3 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
40054
+ AUTHORITY_OVERRIDE_HEADERS3 = 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 join30 } from "path";
40565
+ import { basename as basename11, dirname as dirname24, isAbsolute as isAbsolute25, join as join31 } 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 = join30(scriptDir, `.hooks-verified-${randomBytes2(12).toString("hex")}.${interpreter.tempExt}`);
40636
+ const tempPath = join31(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 join31 } from "path";
40728
+ import { join as join32 } from "path";
40729
40729
  import { tmpdir as tmpdir2 } from "os";
40730
40730
  function manifestAt(dir) {
40731
- const path = join31(dir, "manifest.json");
40731
+ const path = join32(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(join31(tmpdir2(), "hooks-install-"));
40755
- const proc = Bun.spawn(["git", "clone", "--depth", "1", "--quiet", gitUrl, join31(tmp, "repo")], {
40754
+ const tmp = mkdtempSync(join32(tmpdir2(), "hooks-install-"));
40755
+ const proc = Bun.spawn(["git", "clone", "--depth", "1", "--quiet", gitUrl, join32(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 join31(tmp, "repo");
40768
+ return join32(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 join32 } from "path";
42007
+ import { dirname as dirname25, join as join33 } from "path";
42008
42008
  import { fileURLToPath as fileURLToPath4 } from "url";
42009
42009
  function packageVersion() {
42010
42010
  try {
42011
- const pkgPath = join32(dirname25(fileURLToPath4(import.meta.url)), "..", "package.json");
42011
+ const pkgPath = join33(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 join33, dirname as dirname26 } from "path";
42313
+ import { join as join34, 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(join33(hookDir, "src", "hook.ts"))) {
42547
+ if (!existsSync17(join34(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 = join33(hookPath, "README.md");
42591
+ const readmePath = join34(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 = join33(__dirname3, rel);
43321
+ const p = join34(__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 join34 } from "path";
43400
+ import { dirname as dirname27, join as join35 } 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 = join34(directory2, part);
43458
+ directory2 = join35(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 = join34(directory2, operationId);
43468
+ const operation = join35(directory2, operationId);
43469
43469
  mkdirSync15(operation, { mode: 448 });
43470
43470
  syncDirectory4(directory2);
43471
43471
  if (before)
43472
- exclusive3(join34(operation, "binding.before"), before.raw);
43473
- exclusive3(join34(operation, "intent.json"), JSON.stringify({ operationId, target, expectedSHA256, desiredSHA256: digest4 }) + `
43472
+ exclusive3(join35(operation, "binding.before"), before.raw);
43473
+ exclusive3(join35(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(join34(operation, "receipt.json"), JSON.stringify(receipt) + `
43487
+ exclusive3(join35(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 resolve21 } from "path";
43511
+ import { resolve as resolve23 } from "path";
43512
43512
 
43513
43513
  // src/lib/claude-safety-check.ts
43514
43514
  init_native_safety();
@@ -43627,16 +43627,25 @@ async function verifyClaudeSafetyConfiguration(options = {}, dependencies = {})
43627
43627
  // src/cli/index.tsx
43628
43628
  init_codex_safety_trust();
43629
43629
 
43630
- // node_modules/@hasna/events/dist/commander.js
43630
+ // ../../../../../../../repos/clones/hasna/apps/apps/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";
43633
43635
  import { existsSync as existsSync13 } from "fs";
43634
43636
  import { homedir as homedir13 } from "os";
43635
- import { join as join20 } from "path";
43637
+ import { join as join20, resolve as resolve20 } from "path";
43638
+ import { homedir as pathsResolverHomedir3 } from "os";
43639
+ import { join as pathsResolverJoin3 } from "path";
43636
43640
  import { createHmac, timingSafeEqual } from "crypto";
43641
+ import { lookup as dnsLookup } from "dns/promises";
43642
+ import { isIP } from "net";
43637
43643
  import { randomUUID as randomUUID7 } from "crypto";
43638
43644
  import { spawn as spawn3 } from "child_process";
43645
+ import { request as nodeHttpRequest } from "http";
43646
+ import { request as nodeHttpsRequest } from "https";
43639
43647
  import { randomUUID as randomUUID22 } from "crypto";
43648
+ import { createRequire as createRequire2 } from "module";
43640
43649
  function getPathValue(input2, path) {
43641
43650
  return path.split(".").reduce((value, part) => {
43642
43651
  if (value && typeof value === "object" && part in value) {
@@ -43732,13 +43741,103 @@ function channelMatchesEvent(channel, event) {
43732
43741
  return true;
43733
43742
  return channel.filters.some((filter) => eventMatchesFilter(event, filter));
43734
43743
  }
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
+ }
43735
43802
  var HASNA_EVENTS_DIR_ENV = "HASNA_EVENTS_DIR";
43736
43803
  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
+ }
43737
43836
  var LOCAL_JSON_EVENT_CURSOR_PREFIX = "local-json-v1:";
43738
43837
  var DEFAULT_EVENT_PAGE_LIMIT = 100;
43739
43838
  var MAX_EVENT_PAGE_LIMIT = 1000;
43740
43839
  function getEventsDataDir(override) {
43741
- return override || process.env[HASNA_EVENTS_DIR_ENV] || process.env[HASNA_EVENTS_HOME_ENV] || join20(homedir13(), ".hasna", "events");
43840
+ return override || getEventsHome();
43742
43841
  }
43743
43842
  function getActiveEventsDirEnv() {
43744
43843
  if (process.env[HASNA_EVENTS_DIR_ENV])
@@ -43754,12 +43853,12 @@ class JsonEventsStore {
43754
43853
  channelsPath;
43755
43854
  eventsPath;
43756
43855
  deliveriesPath;
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");
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");
43763
43862
  }
43764
43863
  async init() {
43765
43864
  await mkdir(this.dataDir, { recursive: true, mode: 448 });
@@ -43876,7 +43975,7 @@ class JsonEventsStore {
43876
43975
  };
43877
43976
  }
43878
43977
  async ensureArrayFile(path) {
43879
- if (!existsSync13(path)) {
43978
+ if (!existsSync22(path)) {
43880
43979
  await writeFile(path, `[]
43881
43980
  `, { encoding: "utf-8", mode: 384 });
43882
43981
  }
@@ -43906,7 +44005,7 @@ class JsonEventsStore {
43906
44005
  });
43907
44006
  }
43908
44007
  }
43909
- function localJsonRuntime(dataDir3 = getEventsDataDir()) {
44008
+ function localJsonRuntime(dataDir22 = getEventsDataDir()) {
43910
44009
  return {
43911
44010
  mode: "local-files",
43912
44011
  name: "json-events-store",
@@ -43919,7 +44018,7 @@ function localJsonRuntime(dataDir3 = getEventsDataDir()) {
43919
44018
  durable: true,
43920
44019
  idempotency: "best-effort-local",
43921
44020
  replayCursors: true,
43922
- description: `Local JSON files in ${dataDir3}; no SQLite, Postgres, S3, or AWS runtime is configured by this store.`
44021
+ description: `Local JSON files in ${dataDir22}; no SQLite, Postgres, S3, or AWS runtime is configured by this store.`
43923
44022
  };
43924
44023
  }
43925
44024
  function encodeLocalJsonEventCursor(offset, options = {}) {
@@ -43983,8 +44082,8 @@ function assertCursorFilter(name, cursorValue, optionValue) {
43983
44082
  function findEventByIdentity(events2, identity3) {
43984
44083
  return events2.find((event) => identity3.id !== undefined && event.id === identity3.id || identity3.dedupeKey !== undefined && event.dedupeKey === identity3.dedupeKey);
43985
44084
  }
43986
- async function getEventsStatus(dataDir3) {
43987
- const store = new JsonEventsStore(dataDir3);
44085
+ async function getEventsStatus(dataDir22) {
44086
+ const store = new JsonEventsStore(dataDir22);
43988
44087
  await store.init();
43989
44088
  const [channels, events2, deliveries] = await Promise.all([
43990
44089
  store.listChannels(),
@@ -44026,9 +44125,9 @@ async function getEventsStatus(dataDir3) {
44026
44125
  }
44027
44126
  };
44028
44127
  }
44029
- function statusFile(dataDir3, fileName, records) {
44030
- const path = join20(dataDir3, fileName);
44031
- return { path, exists: existsSync13(path), records };
44128
+ function statusFile(dataDir22, fileName, records) {
44129
+ const path = join22(dataDir22, fileName);
44130
+ return { path, exists: existsSync22(path), records };
44032
44131
  }
44033
44132
  var DEFAULT_SIGNATURE_TOLERANCE_MS = 5 * 60 * 1000;
44034
44133
  function buildSignatureBase(timestamp, body) {
@@ -44038,6 +44137,214 @@ function signPayload(secret, timestamp, body) {
44038
44137
  const digest4 = createHmac("sha256", secret).update(buildSignatureBase(timestamp, body)).digest("hex");
44039
44138
  return `sha256=${digest4}`;
44040
44139
  }
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
+ }
44041
44348
  function now() {
44042
44349
  return new Date().toISOString();
44043
44350
  }
@@ -44068,9 +44375,18 @@ function buildWebhookRequest(event, channel, options = {}) {
44068
44375
  }
44069
44376
  return { body, headers };
44070
44377
  }
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
+ }
44071
44386
  async function dispatchWebhook(event, channel, options = {}) {
44072
44387
  if (!channel.webhook)
44073
44388
  throw new Error(`Channel ${channel.id} has no webhook config`);
44389
+ const webhookUrl = normalizeWebhookUrl(channel.webhook.url);
44074
44390
  const startedAt = now();
44075
44391
  let secret = channel.webhook.secret;
44076
44392
  if (channel.webhook.secretRef) {
@@ -44087,10 +44403,14 @@ async function dispatchWebhook(event, channel, options = {}) {
44087
44403
  }
44088
44404
  const timestamp = (options.now?.() ?? new Date).toISOString();
44089
44405
  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
+ }
44090
44410
  const controller = new AbortController;
44091
44411
  const timeout = setTimeout(() => controller.abort(), channel.webhook.timeoutMs ?? 15000);
44092
44412
  try {
44093
- const response = await (options.fetchImpl ?? fetch)(channel.webhook.url, {
44413
+ const response = await (options.fetchImpl ?? fetch)(webhookUrl, {
44094
44414
  method: "POST",
44095
44415
  headers,
44096
44416
  body,
@@ -44118,6 +44438,130 @@ async function dispatchWebhook(event, channel, options = {}) {
44118
44438
  clearTimeout(timeout);
44119
44439
  }
44120
44440
  }
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
+ }
44121
44565
  function failedAttempt(startedAt, error61) {
44122
44566
  return {
44123
44567
  attempt: 1,
@@ -44146,7 +44590,7 @@ async function dispatchCommand(event, channel) {
44146
44590
  HASNA_EVENT_SCHEMA_VERSION: event.schemaVersion,
44147
44591
  HASNA_EVENT_JSON: eventJson
44148
44592
  };
44149
- return new Promise((resolve16) => {
44593
+ return new Promise((resolve23) => {
44150
44594
  const child = spawn3(channel.command.command, channel.command.args ?? [], {
44151
44595
  cwd: channel.command.cwd,
44152
44596
  env,
@@ -44164,7 +44608,7 @@ async function dispatchCommand(event, channel) {
44164
44608
  });
44165
44609
  child.on("error", (error61) => {
44166
44610
  clearTimeout(timeout);
44167
- resolve16({
44611
+ resolve23({
44168
44612
  attempt: 1,
44169
44613
  status: "failed",
44170
44614
  startedAt,
@@ -44177,7 +44621,7 @@ async function dispatchCommand(event, channel) {
44177
44621
  child.on("close", (code2, signal) => {
44178
44622
  clearTimeout(timeout);
44179
44623
  const success2 = code2 === 0;
44180
- resolve16({
44624
+ resolve23({
44181
44625
  attempt: 1,
44182
44626
  status: success2 ? "success" : "failed",
44183
44627
  startedAt,
@@ -44299,6 +44743,22 @@ function setPath(input2, path, replacement) {
44299
44743
  if (last && last in cursor)
44300
44744
  cursor[last] = replacement;
44301
44745
  }
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;
44302
44762
  function createEvent(input2) {
44303
44763
  return {
44304
44764
  id: input2.id ?? randomUUID22(),
@@ -44327,7 +44787,9 @@ class EventsClient {
44327
44787
  this.transportOptions = {
44328
44788
  fetchImpl: options.fetchImpl,
44329
44789
  secretResolver: options.secretResolver,
44330
- now: options.now
44790
+ now: options.now,
44791
+ tls: options.tls,
44792
+ webhookTargetPolicy: options.webhookTargetPolicy
44331
44793
  };
44332
44794
  this.catalog = options.catalog ?? defaultEventTypeCatalog;
44333
44795
  this.validateCatalogTypes = options.validateCatalogTypes ?? false;
@@ -44614,6 +45076,13 @@ function parseMatcherExpression(value, label) {
44614
45076
  negated: false
44615
45077
  };
44616
45078
  }
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
+ }
44617
45086
  var DEFAULT_EVENT_LIST_LIMIT = 100;
44618
45087
  function parseJsonObject(value, fallback) {
44619
45088
  if (!value)
@@ -44639,7 +45108,7 @@ function parseHeaders(values) {
44639
45108
  function createClient(options) {
44640
45109
  if (options.createClient)
44641
45110
  return options.createClient();
44642
- return new EventsClient({ store: new JsonEventsStore(options.dataDir) });
45111
+ return new EventsClient({ store: new JsonEventsStore(options.dataDir), webhookTargetPolicy: webhookTargetPolicyFromEnv() });
44643
45112
  }
44644
45113
  function print(value, json2, text3) {
44645
45114
  if (json2)
@@ -44720,6 +45189,8 @@ function registerChannelCommands(program2, options) {
44720
45189
  metadata: parseJsonObject(actionOptions.metadata, {})
44721
45190
  }, { honorFilters: actionOptions.honorFilters });
44722
45191
  print(result, json2, `${result.status}: ${result.channelId}`);
45192
+ if (result.status === "failed")
45193
+ process.exitCode = 1;
44723
45194
  } catch (error61) {
44724
45195
  fail(error61, json2);
44725
45196
  }
@@ -44812,7 +45283,7 @@ function replaySummary(events2, deliveries, nextCursor) {
44812
45283
  // src/cli/index.tsx
44813
45284
  import { render } from "ink";
44814
45285
 
44815
- // node_modules/commander/esm.mjs
45286
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/commander@12.1.0/node_modules/commander/esm.mjs
44816
45287
  var import__ = __toESM(require_commander(), 1);
44817
45288
  var {
44818
45289
  program: program2,
@@ -44831,18 +45302,18 @@ var {
44831
45302
  // src/cli/index.tsx
44832
45303
  import chalk2 from "chalk";
44833
45304
  import { existsSync as existsSync18, readFileSync as readFileSync27, rmSync as rmSync6 } from "fs";
44834
- import { join as join35, dirname as dirname28 } from "path";
45305
+ import { join as join36, dirname as dirname28 } from "path";
44835
45306
  import { fileURLToPath as fileURLToPath6 } from "url";
44836
45307
 
44837
45308
  // src/cli/components/App.tsx
44838
45309
  import { useState as useState7 } from "react";
44839
45310
  import { Box as Box8, Text as Text10, useApp, useInput as useInput5 } from "ink";
44840
45311
 
44841
- // node_modules/ink-select-input/build/Indicator.js
45312
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/Indicator.js
44842
45313
  import React from "react";
44843
45314
  import { Box, Text } from "ink";
44844
45315
 
44845
- // node_modules/is-unicode-supported/index.js
45316
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/is-unicode-supported@2.1.0/node_modules/is-unicode-supported/index.js
44846
45317
  import process3 from "process";
44847
45318
  function isUnicodeSupported() {
44848
45319
  const { env } = process3;
@@ -44853,7 +45324,7 @@ function isUnicodeSupported() {
44853
45324
  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";
44854
45325
  }
44855
45326
 
44856
- // node_modules/figures/index.js
45327
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/figures@6.1.0/node_modules/figures/index.js
44857
45328
  var common2 = {
44858
45329
  circleQuestionMark: "(?)",
44859
45330
  questionMarkPrefix: "(?)",
@@ -45129,23 +45600,23 @@ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
45129
45600
  var figures_default = figures;
45130
45601
  var replacements = Object.entries(specialMainSymbols);
45131
45602
 
45132
- // node_modules/ink-select-input/build/Indicator.js
45603
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/Indicator.js
45133
45604
  function Indicator({ isSelected = false }) {
45134
45605
  return React.createElement(Box, { marginRight: 1 }, isSelected ? React.createElement(Text, { color: "blue" }, figures_default.pointer) : React.createElement(Text, null, " "));
45135
45606
  }
45136
45607
  var Indicator_default = Indicator;
45137
- // node_modules/ink-select-input/build/Item.js
45608
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/Item.js
45138
45609
  import * as React2 from "react";
45139
45610
  import { Text as Text2 } from "ink";
45140
45611
  function Item({ isSelected = false, label }) {
45141
45612
  return React2.createElement(Text2, { color: isSelected ? "blue" : undefined }, label);
45142
45613
  }
45143
45614
  var Item_default = Item;
45144
- // node_modules/ink-select-input/build/SelectInput.js
45615
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/SelectInput.js
45145
45616
  import { isDeepStrictEqual } from "util";
45146
45617
  import React3, { useState, useEffect, useRef, useCallback } from "react";
45147
45618
 
45148
- // node_modules/to-rotated/index.js
45619
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/to-rotated@1.0.0/node_modules/to-rotated/index.js
45149
45620
  function toRotated(array3, steps) {
45150
45621
  if (!Array.isArray(array3)) {
45151
45622
  throw new TypeError(`Expected an array, got \`${typeof array3}\`.`);
@@ -45167,7 +45638,7 @@ function toRotated(array3, steps) {
45167
45638
  ];
45168
45639
  }
45169
45640
 
45170
- // node_modules/ink-select-input/build/SelectInput.js
45641
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/ink-select-input@6.2.0+fa875fef9f949ebd/node_modules/ink-select-input/build/SelectInput.js
45171
45642
  import { Box as Box2, useInput } from "ink";
45172
45643
  function SelectInput({ items = [], isFocused = true, initialIndex = 0, indicatorComponent = Indicator_default, itemComponent = Item_default, limit: customLimit, onSelect, onHighlight }) {
45173
45644
  const hasLimit = typeof customLimit === "number" && items.length > customLimit;
@@ -45463,7 +45934,7 @@ function HookSelect({
45463
45934
  import { useState as useState4, useEffect as useEffect3 } from "react";
45464
45935
  import { Box as Box6, Text as Text7, useInput as useInput4 } from "ink";
45465
45936
 
45466
- // node_modules/ink-text-input/build/index.js
45937
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/ink-text-input@6.0.0+fa875fef9f949ebd/node_modules/ink-text-input/build/index.js
45467
45938
  import React5, { useState as useState3, useEffect as useEffect2 } from "react";
45468
45939
  import { Text as Text6, useInput as useInput3 } from "ink";
45469
45940
  import chalk from "chalk";
@@ -45641,7 +46112,7 @@ function SearchView({
45641
46112
  import { useState as useState6, useEffect as useEffect5 } from "react";
45642
46113
  import { Box as Box7, Text as Text9 } from "ink";
45643
46114
 
45644
- // node_modules/ink-spinner/build/index.js
46115
+ // ../../../../../../../repos/clones/hasna/apps/node_modules/.bun/ink-spinner@5.0.0+fa875fef9f949ebd/node_modules/ink-spinner/build/index.js
45645
46116
  var import_cli_spinners = __toESM(require_cli_spinners(), 1);
45646
46117
  import React7, { useState as useState5, useEffect as useEffect4 } from "react";
45647
46118
  import { Text as Text8 } from "ink";
@@ -46008,10 +46479,10 @@ init_native_safety();
46008
46479
 
46009
46480
  // src/lib/sumi-binding.ts
46010
46481
  import { homedir as homedir14 } from "os";
46011
- import { join as join24, sep as sep3 } from "path";
46482
+ import { join as join27, sep as sep3 } from "path";
46012
46483
 
46013
46484
  // hooks/hook-trash-guard/src/binary.ts
46014
- import { dirname as dirname21, isAbsolute as isAbsolute20, join as join22, resolve as resolve20 } from "path";
46485
+ import { dirname as dirname21, isAbsolute as isAbsolute20, join as join24, resolve as resolve21 } from "path";
46015
46486
  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";
46016
46487
  import { spawnSync } from "child_process";
46017
46488
  function trustedOwner(uid2) {
@@ -46033,7 +46504,7 @@ function safeExecutableFile(path, systemBinAlias = false) {
46033
46504
  parent = dirname21(parent);
46034
46505
  continue;
46035
46506
  }
46036
- const next = join22(parent, part), info2 = lstatSync23(next);
46507
+ const next = join24(parent, part), info2 = lstatSync23(next);
46037
46508
  if (systemBinAlias && next === "/bin" && info2.isSymbolicLink() && info2.uid === 0) {
46038
46509
  const target = realpathSync11(next);
46039
46510
  if (!safeBinaryDirectory(target))
@@ -46045,7 +46516,7 @@ function safeExecutableFile(path, systemBinAlias = false) {
46045
46516
  return false;
46046
46517
  parent = next;
46047
46518
  }
46048
- const candidate = join22(parent, name), info = lstatSync23(candidate);
46519
+ const candidate = join24(parent, name), info = lstatSync23(candidate);
46049
46520
  if (!trustedOwner(info.uid))
46050
46521
  return false;
46051
46522
  if (info.isSymbolicLink()) {
@@ -46058,9 +46529,9 @@ function safeExecutableFile(path, systemBinAlias = false) {
46058
46529
  return false;
46059
46530
  }
46060
46531
  function safeInterpreterSearchDirectory(path) {
46061
- if (!isAbsolute20(path) || resolve20(path) !== (path.replace(/\/+$/, "") || "/"))
46532
+ if (!isAbsolute20(path) || resolve21(path) !== (path.replace(/\/+$/, "") || "/"))
46062
46533
  return false;
46063
- for (let cursor = resolve20(path);; cursor = dirname21(cursor)) {
46534
+ for (let cursor = resolve21(path);; cursor = dirname21(cursor)) {
46064
46535
  try {
46065
46536
  lstatSync23(cursor);
46066
46537
  return safeBinaryDirectory(cursor);
@@ -46092,7 +46563,7 @@ function safeScriptInterpreter(executable2, pathValue) {
46092
46563
  for (const dir of pathValue.split(":").slice(0, 64)) {
46093
46564
  if (!safeInterpreterSearchDirectory(dir))
46094
46565
  return false;
46095
- const interpreter = resolve20(dir, "bun");
46566
+ const interpreter = resolve21(dir, "bun");
46096
46567
  try {
46097
46568
  if (!statSync(interpreter).isFile())
46098
46569
  continue;
@@ -46127,7 +46598,7 @@ function inspectTrashBinary(env = process.env) {
46127
46598
  for (const dir of pathValue.split(":").slice(0, 64)) {
46128
46599
  if (!isAbsolute20(dir) || Date.now() >= deadline)
46129
46600
  continue;
46130
- const candidate = resolve20(dir, "trash");
46601
+ const candidate = resolve21(dir, "trash");
46131
46602
  try {
46132
46603
  const stat2 = statSync(candidate);
46133
46604
  if (!stat2.isFile() || !trustedOwner(stat2.uid) || (stat2.mode & 73) === 0 || (stat2.mode & 18) !== 0) {
@@ -46135,7 +46606,7 @@ function inspectTrashBinary(env = process.env) {
46135
46606
  continue;
46136
46607
  }
46137
46608
  const executable2 = realpathSync11(candidate);
46138
- if (!safeBinaryDirectory(resolve20(dir)) || !safeBinaryDirectory(dirname21(executable2))) {
46609
+ if (!safeBinaryDirectory(resolve21(dir)) || !safeBinaryDirectory(dirname21(executable2))) {
46139
46610
  reject("unsafe_directory");
46140
46611
  continue;
46141
46612
  }
@@ -46143,15 +46614,15 @@ function inspectTrashBinary(env = process.env) {
46143
46614
  reject("unsafe_directory");
46144
46615
  continue;
46145
46616
  }
46146
- const packageRoot = resolve20(dirname21(executable2), "../..");
46147
- const manifestPath = join22(packageRoot, "package.json");
46617
+ const packageRoot = resolve21(dirname21(executable2), "../..");
46618
+ const manifestPath = join24(packageRoot, "package.json");
46148
46619
  const manifestStat = statSync(manifestPath);
46149
46620
  if (!manifestStat.isFile() || !trustedOwner(manifestStat.uid) || manifestStat.size > 16384 || (manifestStat.mode & 18) !== 0 || lstatSync23(manifestPath).isSymbolicLink()) {
46150
46621
  reject("unsafe_manifest");
46151
46622
  continue;
46152
46623
  }
46153
46624
  const manifest = JSON.parse(readFileSync17(manifestPath, "utf8"));
46154
- if (manifest.name !== "@hasna/trash" || typeof manifest.version !== "string" || typeof manifest.bin?.trash !== "string" || realpathSync11(resolve20(packageRoot, manifest.bin.trash)) !== executable2) {
46625
+ if (manifest.name !== "@hasna/trash" || typeof manifest.version !== "string" || typeof manifest.bin?.trash !== "string" || realpathSync11(resolve21(packageRoot, manifest.bin.trash)) !== executable2) {
46155
46626
  reject("unrecognized_package");
46156
46627
  continue;
46157
46628
  }
@@ -46196,7 +46667,7 @@ function failure(code2, reason) {
46196
46667
  return { ok: false, target: "sumi", code: code2, ...reason ? { reason: reason.slice(0, 300) } : {} };
46197
46668
  }
46198
46669
  function nativeSafetyBindingDurable(worker, home) {
46199
- return !(worker.startsWith(join24(home, ".bun") + sep3) || worker.includes(`${sep3}node_modules${sep3}.bun${sep3}`));
46670
+ return !(worker.startsWith(join27(home, ".bun") + sep3) || worker.includes(`${sep3}node_modules${sep3}.bun${sep3}`));
46200
46671
  }
46201
46672
  async function provisionSumiSafetyBinding(options = {}) {
46202
46673
  const home = options.home ?? homedir14();
@@ -46271,7 +46742,7 @@ init_transport2();
46271
46742
  init_db();
46272
46743
  import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
46273
46744
  var __dirname4 = dirname28(fileURLToPath6(import.meta.url));
46274
- var pkgPath = existsSync18(join35(__dirname4, "..", "package.json")) ? join35(__dirname4, "..", "package.json") : join35(__dirname4, "..", "..", "package.json");
46745
+ var pkgPath = existsSync18(join36(__dirname4, "..", "package.json")) ? join36(__dirname4, "..", "package.json") : join36(__dirname4, "..", "..", "package.json");
46275
46746
  var pkg2 = JSON.parse(readFileSync27(pkgPath, "utf-8"));
46276
46747
  var program3 = new Command;
46277
46748
  function resolveScope(options) {
@@ -46504,7 +46975,7 @@ program3.command("init").description("Register a new agent profile with a unique
46504
46975
  if (profile.name) {
46505
46976
  console.log(` ${chalk2.dim("Name:")} ${profile.name}`);
46506
46977
  }
46507
- console.log(` ${chalk2.dim("Profile:")} ${join35(getProfilesDir(), `${profile.agent_id}.json`)}`);
46978
+ console.log(` ${chalk2.dim("Profile:")} ${join36(getProfilesDir(), `${profile.agent_id}.json`)}`);
46508
46979
  console.log();
46509
46980
  console.log(chalk2.dim(" Install hooks with this profile:"));
46510
46981
  console.log(` hooks install gitguard --profile ${profile.agent_id}`);
@@ -47159,7 +47630,7 @@ program3.command("doctor").option("-g, --global", "Check global settings", false
47159
47630
  continue;
47160
47631
  }
47161
47632
  const hookDir = getHookPath(name);
47162
- const hookScript = join35(hookDir, "src", "hook.ts");
47633
+ const hookScript = join36(hookDir, "src", "hook.ts");
47163
47634
  if (!existsSync18(hookScript)) {
47164
47635
  issues.push({ hook: name, issue: "Missing src/hook.ts in package", severity: "error" });
47165
47636
  hookHealthy = false;
@@ -47370,7 +47841,7 @@ program3.command("docs").argument("[hook]", "Hook name (shows general docs if om
47370
47841
  return;
47371
47842
  }
47372
47843
  const hookPath = getHookPath(hook);
47373
- const readmePath = join35(hookPath, "README.md");
47844
+ const readmePath = join36(hookPath, "README.md");
47374
47845
  let readme = "";
47375
47846
  if (existsSync18(readmePath)) {
47376
47847
  readme = readFileSync27(readmePath, "utf-8");
@@ -48168,7 +48639,7 @@ safety.command("verify").requiredOption("--target <target>", "sumi, codex or cla
48168
48639
  throw new ClaudeSafetyError("settings_invalid");
48169
48640
  console.log(JSON.stringify(await verifyClaudeSafetyConfiguration({
48170
48641
  cwd: options.cwd,
48171
- ...process.env.CLAUDE_CONFIG_DIR ? { userSettingsPath: resolve21(process.env.CLAUDE_CONFIG_DIR, "settings.json") } : {}
48642
+ ...process.env.CLAUDE_CONFIG_DIR ? { userSettingsPath: resolve23(process.env.CLAUDE_CONFIG_DIR, "settings.json") } : {}
48172
48643
  })));
48173
48644
  } catch (error61) {
48174
48645
  console.log(JSON.stringify({ ok: false, target: "claude", code: error61 instanceof ClaudeSafetyError ? error61.code : "settings_invalid", nativeAdoptionVerified: false }));