@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/hooks-mcp.js +2 -2
- package/bin/index.js +585 -114
- package/bin/serve.js +9 -9
- package/dist/index.js +13 -13
- package/dist/sdk/index.js +1 -1
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -2516,7 +2516,7 @@ var init_codex_settings = __esm(() => {
|
|
|
2516
2516
|
snapshots = new WeakMap;
|
|
2517
2517
|
});
|
|
2518
2518
|
|
|
2519
|
-
//
|
|
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
|
|
39038
|
+
import { join as join29 } from "path";
|
|
39039
39039
|
function getProfilesDir() {
|
|
39040
|
-
const newDir =
|
|
39041
|
-
const oldDir =
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
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 >
|
|
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(
|
|
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 =
|
|
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 >
|
|
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,
|
|
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,
|
|
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[
|
|
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,
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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",
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
40038
|
-
|
|
40039
|
-
|
|
40040
|
-
|
|
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
|
-
|
|
40054
|
-
|
|
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
|
|
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 =
|
|
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
|
|
40728
|
+
import { join as join32 } from "path";
|
|
40729
40729
|
import { tmpdir as tmpdir2 } from "os";
|
|
40730
40730
|
function manifestAt(dir) {
|
|
40731
|
-
const path =
|
|
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(
|
|
40755
|
-
const proc = Bun.spawn(["git", "clone", "--depth", "1", "--quiet", gitUrl,
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
43468
|
+
const operation = join35(directory2, operationId);
|
|
43469
43469
|
mkdirSync15(operation, { mode: 448 });
|
|
43470
43470
|
syncDirectory4(directory2);
|
|
43471
43471
|
if (before)
|
|
43472
|
-
exclusive3(
|
|
43473
|
-
exclusive3(
|
|
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(
|
|
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
|
|
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
|
-
//
|
|
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 ||
|
|
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(
|
|
43758
|
-
this.dataDir =
|
|
43759
|
-
this.runtime = localJsonRuntime(
|
|
43760
|
-
this.channelsPath =
|
|
43761
|
-
this.eventsPath =
|
|
43762
|
-
this.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");
|
|
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 (!
|
|
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(
|
|
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 ${
|
|
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(
|
|
43987
|
-
const store = new JsonEventsStore(
|
|
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(
|
|
44030
|
-
const path =
|
|
44031
|
-
return { path, exists:
|
|
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)(
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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) ||
|
|
46532
|
+
if (!isAbsolute20(path) || resolve21(path) !== (path.replace(/\/+$/, "") || "/"))
|
|
46062
46533
|
return false;
|
|
46063
|
-
for (let 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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
46147
|
-
const manifestPath =
|
|
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(
|
|
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(
|
|
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(
|
|
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:")} ${
|
|
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 =
|
|
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 =
|
|
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:
|
|
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 }));
|