@hasna/hooks 0.12.2 → 0.12.3
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/README.md +7 -5
- package/bin/index.js +19 -36
- package/bin/native-safety-entry.js +20 -15
- package/dist/index.js +1 -1
- package/dist/lib/codex-safety-check.d.ts +1 -1
- package/hooks/hook-workspace-repos-guard/README.md +20 -0
- package/hooks/hook-workspace-repos-guard/src/hook.ts +414 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -309,9 +309,11 @@ Known limits of the native entry:
|
|
|
309
309
|
harness environment are outside it (details in the guard's README).
|
|
310
310
|
- Codex's input into a running unified exec session (`write_stdin`) has not
|
|
311
311
|
been verified to pass through PreToolUse.
|
|
312
|
-
- The repository guard
|
|
313
|
-
|
|
314
|
-
|
|
312
|
+
- The repository guard reads a here-document body as data only when every
|
|
313
|
+
command word of the command is a data command such as `cat`, `git commit`
|
|
314
|
+
or `gh pr` (the list is in the guard's README). With any other command word
|
|
315
|
+
it reads the body line by line, so prose in such a body that mentions a
|
|
316
|
+
delete command can still be refused inside a protected checkout.
|
|
315
317
|
|
|
316
318
|
## Codex safety readiness
|
|
317
319
|
|
|
@@ -331,8 +333,8 @@ architecture (arm64 or x64); script launchers are refused before execution. When
|
|
|
331
333
|
Codex is installed through npm, pass the platform package's native binary rather
|
|
332
334
|
than its JavaScript launcher. Executable ownership, permissions, ancestry and
|
|
333
335
|
bytes are checked. Supported protocol versions are 0.153.0, 0.154.0,
|
|
334
|
-
0.154.0-alpha.6.1, 0.155.0, 0.155.1, 0.156.1, 0.157.0, 0.157.1, 0.158.0, 0.159.0, 0.159.2
|
|
335
|
-
and 0.
|
|
336
|
+
0.154.0-alpha.6.1, 0.155.0, 0.155.1, 0.156.1, 0.157.0, 0.157.1, 0.158.0, 0.159.0, 0.159.2,
|
|
337
|
+
0.159.3 and 0.160.0;
|
|
336
338
|
other versions refuse pending compatibility validation. Updating Codex can
|
|
337
339
|
therefore require a compatible Hooks release before native safety verification
|
|
338
340
|
and trust provisioning succeed. Keep existing hook definitions and trust intact
|
package/bin/index.js
CHANGED
|
@@ -35391,7 +35391,7 @@ var init_codex_safety_check = __esm(() => {
|
|
|
35391
35391
|
init_native_readiness_command();
|
|
35392
35392
|
init_native_safety2();
|
|
35393
35393
|
init_native_readiness();
|
|
35394
|
-
SUPPORTED_CODEX_SAFETY_VERSIONS = ["codex-cli 0.153.0", "codex-cli 0.154.0", "codex-cli 0.154.0-alpha.6.1", "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", "codex-cli 0.158.0", "codex-cli 0.159.0", "codex-cli 0.159.2", "codex-cli 0.159.3"];
|
|
35394
|
+
SUPPORTED_CODEX_SAFETY_VERSIONS = ["codex-cli 0.153.0", "codex-cli 0.154.0", "codex-cli 0.154.0-alpha.6.1", "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", "codex-cli 0.158.0", "codex-cli 0.159.0", "codex-cli 0.159.2", "codex-cli 0.159.3", "codex-cli 0.160.0"];
|
|
35395
35395
|
versions = new Set(SUPPORTED_CODEX_SAFETY_VERSIONS);
|
|
35396
35396
|
CodexSafetyError = class CodexSafetyError extends Error {
|
|
35397
35397
|
code;
|
|
@@ -39289,7 +39289,7 @@ import { closeSync as closeSync22, fstatSync as fstatSync22, openSync as openSyn
|
|
|
39289
39289
|
import { O_NOFOLLOW as O_NOFOLLOW2, O_NONBLOCK as O_NONBLOCK2, O_RDONLY as O_RDONLY2 } from "constants";
|
|
39290
39290
|
import { hostname as osHostname } from "os";
|
|
39291
39291
|
import { isAbsolute as isAbsolute21, join as join28 } from "path";
|
|
39292
|
-
import { createRequire as
|
|
39292
|
+
import { createRequire as createRequire2 } from "module";
|
|
39293
39293
|
import { fileURLToPath as fileURLToPath22 } from "url";
|
|
39294
39294
|
import { closeSync as closeSync20, fstatSync as fstatSync19, lstatSync as lstatSync24, openSync as openSync20, readFileSync as readFileSync20, realpathSync as realpathSync12, statSync as statSync2 } from "fs";
|
|
39295
39295
|
import { O_NOFOLLOW, O_NONBLOCK, O_RDONLY } from "constants";
|
|
@@ -39372,7 +39372,7 @@ function entryPoint(directory2) {
|
|
|
39372
39372
|
let pkg;
|
|
39373
39373
|
try {
|
|
39374
39374
|
const stat2 = fstatSync19(fd);
|
|
39375
|
-
if (!stat2.isFile() || stat2.size >
|
|
39375
|
+
if (!stat2.isFile() || stat2.size > MAX_PACKAGE_BYTES2)
|
|
39376
39376
|
throw new Error("Invalid Secrets package metadata");
|
|
39377
39377
|
pkg = JSON.parse(readFileSync20(fd, "utf8"));
|
|
39378
39378
|
} finally {
|
|
@@ -39519,7 +39519,7 @@ function readAppConfigFile(path) {
|
|
|
39519
39519
|
const uid2 = process.getuid?.() ?? process.geteuid?.();
|
|
39520
39520
|
if (uid2 !== undefined && before.uid !== uid2)
|
|
39521
39521
|
unsafe("the file is not owned by the current user");
|
|
39522
|
-
if (before.size >
|
|
39522
|
+
if (before.size > MAX_CREDENTIAL_FILE_BYTES2)
|
|
39523
39523
|
unsafe("the file exceeds the size limit");
|
|
39524
39524
|
const bytes = readFileSync22(fd);
|
|
39525
39525
|
const after = fstatSync22(fd);
|
|
@@ -39611,13 +39611,13 @@ function sealCredential(fields) {
|
|
|
39611
39611
|
configurable: false
|
|
39612
39612
|
});
|
|
39613
39613
|
}
|
|
39614
|
-
Object.defineProperty(sealed,
|
|
39614
|
+
Object.defineProperty(sealed, INSPECT_CUSTOM2, {
|
|
39615
39615
|
value: () => ({ ...visible, apiKey: "[redacted]" }),
|
|
39616
39616
|
enumerable: false,
|
|
39617
39617
|
writable: false,
|
|
39618
39618
|
configurable: false
|
|
39619
39619
|
});
|
|
39620
|
-
Object.defineProperty(sealed,
|
|
39620
|
+
Object.defineProperty(sealed, CREDENTIAL_SEAL2, {
|
|
39621
39621
|
value: true,
|
|
39622
39622
|
enumerable: false,
|
|
39623
39623
|
writable: false,
|
|
@@ -39648,7 +39648,7 @@ function firstEnvValue(env, keys2) {
|
|
|
39648
39648
|
return null;
|
|
39649
39649
|
}
|
|
39650
39650
|
function isAmbientEnvironment(env) {
|
|
39651
|
-
return env === process.env || env[
|
|
39651
|
+
return env === process.env || env[AMBIENT_ENVIRONMENT2] === true;
|
|
39652
39652
|
}
|
|
39653
39653
|
function defaultKeychainRunner(argv) {
|
|
39654
39654
|
const result = spawnSync2(KEYCHAIN_SECURITY_BIN, [...argv], {
|
|
@@ -39742,7 +39742,7 @@ function snapshotClientEnvironment(name, env) {
|
|
|
39742
39742
|
snapshot2[key] = descriptor.value;
|
|
39743
39743
|
}
|
|
39744
39744
|
if (ambient) {
|
|
39745
|
-
Object.defineProperty(snapshot2,
|
|
39745
|
+
Object.defineProperty(snapshot2, AMBIENT_ENVIRONMENT2, {
|
|
39746
39746
|
value: true,
|
|
39747
39747
|
enumerable: false,
|
|
39748
39748
|
writable: false,
|
|
@@ -39915,7 +39915,7 @@ async function completePointerCredential(name, pointerResolution, env = process.
|
|
|
39915
39915
|
let secretsSdk;
|
|
39916
39916
|
try {
|
|
39917
39917
|
const sdkUrl = resolveInstalledSecrets(import.meta.url);
|
|
39918
|
-
secretsSdk =
|
|
39918
|
+
secretsSdk = requireSecretsSdk2(fileURLToPath22(sdkUrl));
|
|
39919
39919
|
} catch {
|
|
39920
39920
|
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]);
|
|
39921
39921
|
}
|
|
@@ -40151,9 +40151,9 @@ function credentialDiskSourcesForMessage(name, env) {
|
|
|
40151
40151
|
const paths = credentialDiskSources(name, env);
|
|
40152
40152
|
return paths.length > 0 ? paths.join(" or ") : "<no HOME or HASNA_HOME set in this environment, so no credential file was consulted>";
|
|
40153
40153
|
}
|
|
40154
|
-
var CREDENTIAL_PROFILE_ENV_KEY = "HASNA_PROFILE", PACKAGE = "@hasna/secrets",
|
|
40154
|
+
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;
|
|
40155
40155
|
var init_transport = __esm(() => {
|
|
40156
|
-
|
|
40156
|
+
MAX_PACKAGE_BYTES2 = 1024 * 1024;
|
|
40157
40157
|
CredentialResolutionError = class CredentialResolutionError extends Error {
|
|
40158
40158
|
appName;
|
|
40159
40159
|
attempted;
|
|
@@ -40172,16 +40172,16 @@ var init_transport = __esm(() => {
|
|
|
40172
40172
|
this.path = path;
|
|
40173
40173
|
}
|
|
40174
40174
|
};
|
|
40175
|
-
|
|
40175
|
+
MAX_CREDENTIAL_FILE_BYTES2 = 64 * 1024;
|
|
40176
40176
|
SAFE_APP_SLUG = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
40177
40177
|
SAFE_PROFILE = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
|
|
40178
40178
|
ILLEGAL_IN_HEADER_VALUE = /[^\t\x20-\x7e]/;
|
|
40179
40179
|
VAULT_POINTER_SHAPE = /^[a-z0-9][a-z0-9-]*(?:\/[a-z0-9][a-z0-9-_.]*){2,}$/;
|
|
40180
40180
|
CREDENTIAL_SHAPED_KEY = /(?:^|_)(?:API_KEY|KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH)(?:_|$)/;
|
|
40181
|
-
|
|
40182
|
-
|
|
40183
|
-
|
|
40184
|
-
|
|
40181
|
+
INSPECT_CUSTOM2 = Symbol.for("nodejs.util.inspect.custom");
|
|
40182
|
+
CREDENTIAL_SEAL2 = Symbol.for("hasna:contracts:sealedCredential");
|
|
40183
|
+
AMBIENT_ENVIRONMENT2 = Symbol.for("hasna:contracts:ambientClientEnvironment");
|
|
40184
|
+
requireSecretsSdk2 = createRequire2(import.meta.url);
|
|
40185
40185
|
ASCII_CONTROL_PATTERN = /[\u0000-\u001f\u007f]/;
|
|
40186
40186
|
DNS_LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
40187
40187
|
ClientTransportConfigurationError = class ClientTransportConfigurationError extends Error {
|
|
@@ -40194,8 +40194,8 @@ var init_transport = __esm(() => {
|
|
|
40194
40194
|
this.sources = Object.freeze([...sources]);
|
|
40195
40195
|
}
|
|
40196
40196
|
};
|
|
40197
|
-
|
|
40198
|
-
|
|
40197
|
+
IDEMPOTENT_METHODS2 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
40198
|
+
AUTHORITY_OVERRIDE_HEADERS2 = new Set([
|
|
40199
40199
|
"host",
|
|
40200
40200
|
":authority",
|
|
40201
40201
|
"forwarded",
|
|
@@ -43772,7 +43772,7 @@ async function verifyClaudeSafetyConfiguration(options = {}, dependencies = {})
|
|
|
43772
43772
|
// src/cli/index.tsx
|
|
43773
43773
|
init_codex_safety_trust();
|
|
43774
43774
|
|
|
43775
|
-
//
|
|
43775
|
+
// ../../node_modules/.bun/@hasna+events@0.1.18/node_modules/@hasna/events/dist/commander.js
|
|
43776
43776
|
import { chmod, mkdir, readFile as readFile2, rename, writeFile } from "fs/promises";
|
|
43777
43777
|
import { Buffer as Buffer2 } from "buffer";
|
|
43778
43778
|
import { existsSync as existsSync22 } from "fs";
|
|
@@ -43790,7 +43790,6 @@ import { spawn as spawn3 } from "child_process";
|
|
|
43790
43790
|
import { request as nodeHttpRequest } from "http";
|
|
43791
43791
|
import { request as nodeHttpsRequest } from "https";
|
|
43792
43792
|
import { randomUUID as randomUUID22 } from "crypto";
|
|
43793
|
-
import { createRequire as createRequire2 } from "module";
|
|
43794
43793
|
function getPathValue(input2, path) {
|
|
43795
43794
|
return path.split(".").reduce((value, part) => {
|
|
43796
43795
|
if (value && typeof value === "object" && part in value) {
|
|
@@ -44888,22 +44887,6 @@ function setPath(input2, path, replacement) {
|
|
|
44888
44887
|
if (last && last in cursor)
|
|
44889
44888
|
cursor[last] = replacement;
|
|
44890
44889
|
}
|
|
44891
|
-
var MAX_PACKAGE_BYTES2 = 1024 * 1024;
|
|
44892
|
-
var MAX_CREDENTIAL_FILE_BYTES2 = 64 * 1024;
|
|
44893
|
-
var INSPECT_CUSTOM2 = Symbol.for("nodejs.util.inspect.custom");
|
|
44894
|
-
var CREDENTIAL_SEAL2 = Symbol.for("hasna:contracts:sealedCredential");
|
|
44895
|
-
var AMBIENT_ENVIRONMENT2 = Symbol.for("hasna:contracts:ambientClientEnvironment");
|
|
44896
|
-
var requireSecretsSdk2 = createRequire2(import.meta.url);
|
|
44897
|
-
var IDEMPOTENT_METHODS2 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
44898
|
-
var AUTHORITY_OVERRIDE_HEADERS2 = new Set([
|
|
44899
|
-
"host",
|
|
44900
|
-
":authority",
|
|
44901
|
-
"forwarded",
|
|
44902
|
-
"x-forwarded-host",
|
|
44903
|
-
"x-original-host"
|
|
44904
|
-
]);
|
|
44905
|
-
var MAX_ENVELOPE_BYTES = 256 * 1024;
|
|
44906
|
-
var MAX_REQUEST_BYTES = MAX_ENVELOPE_BYTES * 2 + 8192;
|
|
44907
44890
|
function createEvent(input2) {
|
|
44908
44891
|
return {
|
|
44909
44892
|
id: input2.id ?? randomUUID22(),
|