@hasna/hooks 0.10.5 → 0.10.7

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.
@@ -0,0 +1,32 @@
1
+ import { verifyNativeSafetyCommand } from "../native-safety.js";
2
+ export declare class ClaudeSafetyError extends Error {
3
+ readonly code: "settings_unsafe" | "settings_invalid" | "settings_changed" | "hooks_disabled" | "guard_missing" | "guard_ambiguous" | "guard_definition_invalid" | "guard_failed";
4
+ constructor(code: "settings_unsafe" | "settings_invalid" | "settings_changed" | "hooks_disabled" | "guard_missing" | "guard_ambiguous" | "guard_definition_invalid" | "guard_failed");
5
+ }
6
+ export interface ClaudeSafetyOptions {
7
+ home?: string;
8
+ cwd?: string;
9
+ /** Exact user settings path, for the native CLAUDE_CONFIG_DIR override. */
10
+ userSettingsPath?: string;
11
+ /** An already-resolved main-checkout local file may be outside cwd. */
12
+ localSettingsPath?: string;
13
+ }
14
+ /** This does not claim to reproduce Claude's MDM/server/CLI policy merge.
15
+ * It checks these selected native settings sources and their exact bytes. */
16
+ export declare function verifyClaudeSafetyConfiguration(options?: ClaudeSafetyOptions, dependencies?: {
17
+ verify?: typeof verifyNativeSafetyCommand;
18
+ }): Promise<{
19
+ ok: true;
20
+ target: "claude";
21
+ cwd: string;
22
+ configurationVerified: boolean;
23
+ guardVerified: boolean;
24
+ sources: {
25
+ path: string;
26
+ sha256: string | null;
27
+ }[];
28
+ guardSHA256: string;
29
+ runtimePolicyVerified: boolean;
30
+ nativeDiscoveryVerified: boolean;
31
+ nativeAdoptionVerified: boolean;
32
+ }>;
@@ -0,0 +1,58 @@
1
+ import { verifyNativeSafetyCommand } from "../native-safety.js";
2
+ export type CodexSafetyCode = "native_unavailable" | "native_unsafe_executable" | "native_executable_required" | "native_unsupported" | "native_failed" | "native_discovery_failed" | "hooks_disabled" | "guard_missing" | "guard_ambiguous" | "guard_definition_invalid" | "guard_disabled" | "guard_untrusted" | "guard_changed" | "guard_failed";
3
+ export declare class CodexSafetyError extends Error {
4
+ readonly code: CodexSafetyCode;
5
+ constructor(code: CodexSafetyCode);
6
+ }
7
+ export interface CodexSafetyRpc {
8
+ version: string;
9
+ request(method: "hooks/list" | "config/read" | "experimentalFeature/list" | "config/batchWrite", params: unknown): Promise<unknown>;
10
+ close(): Promise<void>;
11
+ }
12
+ export type CodexSafetyOptions = {
13
+ command?: string;
14
+ home?: string;
15
+ cwd?: string;
16
+ codexHome?: string;
17
+ };
18
+ /** Owns only its fresh app-server subprocess. It never reloads a running agent,
19
+ * enrolls trust, starts a model turn or forwards native diagnostic text. */
20
+ export declare function connectCodexSafety(options: Required<Pick<CodexSafetyOptions, "home">> & CodexSafetyOptions): Promise<CodexSafetyRpc>;
21
+ type NativeGuard = {
22
+ key: string;
23
+ command: string;
24
+ currentHash: string;
25
+ sourcePath: string;
26
+ enabled: boolean;
27
+ trustStatus: string;
28
+ };
29
+ /** Select only the exact packaged composite definition in native discovery.
30
+ * A name, a settings file, or a trusted hash by itself is not enough. */
31
+ export declare function selectCodexSafety(discovery: unknown, configuration: unknown, home: string, cwd: string, featureEnabled?: boolean, requireReady?: boolean): NativeGuard;
32
+ export declare function readCodexSafety(rpc: CodexSafetyRpc, home: string, cwd: string, options?: {
33
+ includeLayers?: boolean;
34
+ requireReady?: boolean;
35
+ }): Promise<{
36
+ guard: NativeGuard;
37
+ discovery: unknown;
38
+ configuration: unknown;
39
+ }>;
40
+ /** Two native observations surround stateless guard classification. No requested
41
+ * file operation is executed and no Hooks registry credential is consulted. */
42
+ export declare function verifyCodexNativeSafety(options?: CodexSafetyOptions, dependencies?: {
43
+ connect?: typeof connectCodexSafety;
44
+ verify?: typeof verifyNativeSafetyCommand;
45
+ }): Promise<{
46
+ ok: true;
47
+ target: "codex";
48
+ nativeVersion: string;
49
+ cwd: string;
50
+ key: string;
51
+ currentHash: string;
52
+ enabled: boolean;
53
+ trusted: boolean;
54
+ guardVerified: boolean;
55
+ nativeDiscoveryVerified: boolean;
56
+ nativeAdoptionVerified: boolean;
57
+ }>;
58
+ export {};
@@ -0,0 +1,54 @@
1
+ import { connectCodexSafety, type CodexSafetyOptions } from "./codex-safety-check.js";
2
+ import { verifyNativeSafetyCommand } from "../native-safety.js";
3
+ export declare class CodexTrustError extends Error {
4
+ readonly code: "input_invalid" | "native_changed" | "native_config_invalid" | "preimage_unsafe" | "trust_outcome_uncertain";
5
+ readonly operationId?: string | undefined;
6
+ constructor(code: "input_invalid" | "native_changed" | "native_config_invalid" | "preimage_unsafe" | "trust_outcome_uncertain", operationId?: string | undefined);
7
+ }
8
+ interface Dependencies {
9
+ connect?: typeof connectCodexSafety;
10
+ verify?: typeof verifyNativeSafetyCommand;
11
+ }
12
+ type Options = CodexSafetyOptions;
13
+ export interface CodexTrustPlan {
14
+ schema: "hasna.hooks.codex-safety-trust/v1";
15
+ planDigest: string;
16
+ nativeVersion: string;
17
+ cwd: string;
18
+ key: string;
19
+ currentHash: string;
20
+ configPath: string;
21
+ configVersion: string;
22
+ action: "unchanged" | "trust_and_enable";
23
+ guardVerified: true;
24
+ nativeAdoptionVerified: false;
25
+ }
26
+ export declare function planCodexSafetyTrust(options?: Options, dependencies?: Dependencies): Promise<CodexTrustPlan>;
27
+ export declare function applyCodexSafetyTrust(options: Options & {
28
+ expectedPlanDigest: string;
29
+ }, dependencies?: Dependencies): Promise<{
30
+ ok: boolean;
31
+ changed: boolean;
32
+ operationId: string;
33
+ planDigest: string;
34
+ configVersion: any;
35
+ guardVerified: boolean;
36
+ nativeDiscoveryVerified: boolean;
37
+ nativeAdoptionVerified: boolean;
38
+ unrelatedConfigurationPreserved: boolean;
39
+ } | {
40
+ schema: "hasna.hooks.codex-safety-trust/v1";
41
+ planDigest: string;
42
+ nativeVersion: string;
43
+ cwd: string;
44
+ key: string;
45
+ currentHash: string;
46
+ configPath: string;
47
+ configVersion: string;
48
+ action: "unchanged" | "trust_and_enable";
49
+ guardVerified: true;
50
+ nativeAdoptionVerified: false;
51
+ ok: boolean;
52
+ changed: boolean;
53
+ }>;
54
+ export {};
@@ -1,3 +1,7 @@
1
1
  export declare function readCodexSettings(path: string): Record<string, any>;
2
2
  /** Preserve the exact read version. Never write trust state or config.toml. */
3
- export declare function writeCodexSettings(path: string, settings: Record<string, any>): void;
3
+ export declare function capturedCodexSettings(settings: Record<string, any>): string | null;
4
+ export declare function assertSettingsPreimage(raw: string | null, expected?: string): void;
5
+ export declare function writeCodexSettings(path: string, settings: Record<string, any>, expectedSha256?: string): void;
6
+ /** Shared standalone writer. Managed Claude settings still use Skills. */
7
+ export declare function writeHookSettingsPreimage(path: string, settings: Record<string, any>, before: string | null): void;
@@ -30,6 +30,8 @@ export interface InstallResult {
30
30
  configPath?: string;
31
31
  }
32
32
  export interface InstallOptions {
33
+ /** Optional exact predecessor for a planned native safety registration. */
34
+ expectedSettingsSha256?: string;
33
35
  /** Explicit persistent opt-in for mementos-context; omitted updates retain its current choice. */
34
36
  mementos?: MementosRegistration;
35
37
  scope?: Scope;
@@ -64,6 +66,12 @@ export declare function detectRewriteConflict(name: string, scope: Scope, target
64
66
  /** Injected for tests: the rewrite claim is a registry concern, the overlap is not. */
65
67
  lookup?: (hookName: string) => HookMeta | undefined): string | undefined;
66
68
  export declare function installHook(name: string, options?: InstallOptions): InstallResult;
69
+ /** Render through the installer without writing settings or trust state. */
70
+ export declare function previewNativeSafetyRegistration(target: "codex" | "claude", scope?: Scope): {
71
+ before: string | null;
72
+ after: string;
73
+ command: string;
74
+ };
67
75
  export declare function installHooks(names: string[], options?: InstallOptions): InstallResult[];
68
76
  export declare function getRegisteredHooksForTarget(scope?: Scope, target?: SingleTarget): string[];
69
77
  export declare function getRegisteredHooks(scope?: Scope): string[];
@@ -0,0 +1,52 @@
1
+ import { verifyNativeSafetyCommand } from "../native-safety.js";
2
+ export declare class NativeRegistrationError extends Error {
3
+ readonly code: "input_invalid" | "settings_unsafe" | "settings_invalid" | "settings_changed" | "hooks_disabled" | "registration_conflict" | "guard_failed" | "apply_outcome_uncertain";
4
+ readonly operationId?: string | undefined;
5
+ constructor(code: "input_invalid" | "settings_unsafe" | "settings_invalid" | "settings_changed" | "hooks_disabled" | "registration_conflict" | "guard_failed" | "apply_outcome_uncertain", operationId?: string | undefined);
6
+ }
7
+ export interface NativeRegistrationOptions {
8
+ target: "codex" | "claude";
9
+ }
10
+ export interface NativeRegistrationPlan {
11
+ schema: "hasna.hooks.native-safety-registration/v1";
12
+ target: "codex" | "claude";
13
+ settingsPath: string;
14
+ resolvedPath: string;
15
+ beforeSHA256: string;
16
+ desiredSHA256: string;
17
+ commandSHA256: string;
18
+ action: "unchanged" | "register";
19
+ planDigest: string;
20
+ guardVerified: true;
21
+ nativeAdoptionVerified: false;
22
+ }
23
+ interface Dependencies {
24
+ verify?: typeof verifyNativeSafetyCommand;
25
+ }
26
+ export declare function planNativeSafetyRegistration(options: NativeRegistrationOptions, dependencies?: Dependencies): Promise<NativeRegistrationPlan>;
27
+ export declare function applyNativeSafetyRegistration(options: NativeRegistrationOptions & {
28
+ expectedPlanDigest: string;
29
+ }, dependencies?: Dependencies): Promise<{
30
+ ok: boolean;
31
+ changed: boolean;
32
+ operationId: `${string}-${string}-${string}-${string}-${string}`;
33
+ planDigest: string;
34
+ settingsSHA256: string;
35
+ guardVerified: boolean;
36
+ nativeAdoptionVerified: boolean;
37
+ } | {
38
+ schema: "hasna.hooks.native-safety-registration/v1";
39
+ target: "codex" | "claude";
40
+ settingsPath: string;
41
+ resolvedPath: string;
42
+ beforeSHA256: string;
43
+ desiredSHA256: string;
44
+ commandSHA256: string;
45
+ action: "unchanged" | "register";
46
+ planDigest: string;
47
+ guardVerified: true;
48
+ nativeAdoptionVerified: false;
49
+ ok: boolean;
50
+ changed: boolean;
51
+ }>;
52
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/hooks",
3
- "version": "0.10.5",
3
+ "version": "0.10.7",
4
4
  "description": "Open source hooks library for AI coding agents - Install safety, quality, and automation hooks with a single command",
5
5
  "type": "module",
6
6
  "bin": {