@goodfoot/agent-hooks 1.0.0

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.
Files changed (68) hide show
  1. package/README.md +137 -0
  2. package/dist/agents/antigravity/events.js +42 -0
  3. package/dist/agents/antigravity/hooks.js +59 -0
  4. package/dist/agents/antigravity/index.js +28 -0
  5. package/dist/agents/antigravity/outputs.js +81 -0
  6. package/dist/agents/antigravity/transport.js +84 -0
  7. package/dist/agents/antigravity/types.js +11 -0
  8. package/dist/agents/claude-code/env.js +27 -0
  9. package/dist/agents/claude-code/events.js +87 -0
  10. package/dist/agents/claude-code/hooks.js +1000 -0
  11. package/dist/agents/claude-code/index.js +57 -0
  12. package/dist/agents/claude-code/outputs.js +579 -0
  13. package/dist/agents/claude-code/tool-helpers.js +840 -0
  14. package/dist/agents/claude-code/transport.js +254 -0
  15. package/dist/agents/claude-code/types.js +11 -0
  16. package/dist/agents/codex/cli-support.js +318 -0
  17. package/dist/agents/codex/constants.js +29 -0
  18. package/dist/agents/codex/events.js +68 -0
  19. package/dist/agents/codex/hooks.js +93 -0
  20. package/dist/agents/codex/index.js +21 -0
  21. package/dist/agents/codex/outputs.js +189 -0
  22. package/dist/agents/codex/scaffold.js +273 -0
  23. package/dist/agents/codex/transport.js +139 -0
  24. package/dist/agents/codex/types.js +1 -0
  25. package/dist/cli.js +1357 -0
  26. package/dist/constants.js +39 -0
  27. package/dist/core/define-hook.js +61 -0
  28. package/dist/core/env.js +186 -0
  29. package/dist/core/logger.js +508 -0
  30. package/dist/core/stdin.js +38 -0
  31. package/dist/core/transport.js +231 -0
  32. package/dist/core/types.js +10 -0
  33. package/dist/index.js +17 -0
  34. package/dist/scaffold.js +512 -0
  35. package/package.json +61 -0
  36. package/types/agents/antigravity/events.d.ts +50 -0
  37. package/types/agents/antigravity/hooks.d.ts +76 -0
  38. package/types/agents/antigravity/index.d.ts +27 -0
  39. package/types/agents/antigravity/outputs.d.ts +107 -0
  40. package/types/agents/antigravity/transport.d.ts +47 -0
  41. package/types/agents/antigravity/types.d.ts +58 -0
  42. package/types/agents/claude-code/env.d.ts +27 -0
  43. package/types/agents/claude-code/events.d.ts +69 -0
  44. package/types/agents/claude-code/hooks.d.ts +1182 -0
  45. package/types/agents/claude-code/index.d.ts +23 -0
  46. package/types/agents/claude-code/outputs.d.ts +1160 -0
  47. package/types/agents/claude-code/tool-helpers.d.ts +807 -0
  48. package/types/agents/claude-code/transport.d.ts +119 -0
  49. package/types/agents/claude-code/types.d.ts +557 -0
  50. package/types/agents/codex/cli-support.d.ts +105 -0
  51. package/types/agents/codex/constants.d.ts +10 -0
  52. package/types/agents/codex/events.d.ts +63 -0
  53. package/types/agents/codex/hooks.d.ts +135 -0
  54. package/types/agents/codex/index.d.ts +19 -0
  55. package/types/agents/codex/outputs.d.ts +190 -0
  56. package/types/agents/codex/scaffold.d.ts +14 -0
  57. package/types/agents/codex/transport.d.ts +74 -0
  58. package/types/agents/codex/types.d.ts +131 -0
  59. package/types/cli.d.ts +315 -0
  60. package/types/constants.d.ts +9 -0
  61. package/types/core/define-hook.d.ts +39 -0
  62. package/types/core/env.d.ts +150 -0
  63. package/types/core/logger.d.ts +476 -0
  64. package/types/core/stdin.d.ts +21 -0
  65. package/types/core/transport.d.ts +131 -0
  66. package/types/core/types.d.ts +137 -0
  67. package/types/index.d.ts +18 -0
  68. package/types/scaffold.d.ts +46 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Typed factory functions for Antigravity hooks, built on the shared core
3
+ * {@link ../../core/define-hook.ts|defineHook}.
4
+ *
5
+ * This release ships the typed factory surface and output builders only
6
+ * (plan Step 5, item-6 descope) — no `CONTRACT.md`-derived e2e file, no
7
+ * `./antigravity` export. Every factory injects the advisory allow-list
8
+ * policy gate, so `unexpectedError: "continue"` fails closed at
9
+ * factory-call time for every event ({@link ADVISORY_EVENTS} is empty this
10
+ * release); {@link HookConfigFor} additionally narrows the policy field at
11
+ * compile time.
12
+ *
13
+ * Antigravity's config surface is a single conditional type rather than the
14
+ * separate matcher/no-matcher interface pair Claude Code and Codex use: only
15
+ * two of the five events (`PreToolUse`, `PostToolUse`) carry a `matcher`
16
+ * ({@link EVENTS_WITH_MATCHER} in `events.ts`), and a conditional type on the
17
+ * bound event expresses that distinction without duplicating the base field
18
+ * list twice.
19
+ * @module
20
+ */
21
+ import type { HookContext, UnexpectedErrorHandler, UnexpectedErrorPolicy } from "../../core/types.js";
22
+ import { type AllowedUnexpectedErrorPolicy } from "./events.js";
23
+ import type { PostInvocationOutput, PostToolUseOutput, PreInvocationOutput, PreToolUseOutput, StopOutput } from "./outputs.js";
24
+ import type { HookEventName, PostInvocationInput, PostToolUseInput, PreInvocationInput, PreToolUseInput, StopInput } from "./types.js";
25
+ export type { HookContext, UnexpectedErrorHandler, UnexpectedErrorPolicy };
26
+ /** The two events whose bound config accepts a `matcher`, as a literal union. */
27
+ type EventWithMatcher = "PreToolUse" | "PostToolUse";
28
+ /** The base field list every Antigravity hook config shares. */
29
+ export interface HookConfig {
30
+ matcher?: string;
31
+ timeout?: number;
32
+ unexpectedError?: UnexpectedErrorPolicy;
33
+ onUnexpectedError?: UnexpectedErrorHandler;
34
+ }
35
+ /**
36
+ * Per-event config: `matcher` only appears in the type for
37
+ * {@link EventWithMatcher}, and `unexpectedError` is narrowed per event by
38
+ * the advisory allow-list ({@link AllowedUnexpectedErrorPolicy}).
39
+ * @template TEvent - The event the factory binds.
40
+ */
41
+ export type HookConfigFor<TEvent extends HookEventName> = Omit<HookConfig, "matcher" | "unexpectedError"> & (TEvent extends EventWithMatcher ? Pick<HookConfig, "matcher"> : Record<never, never>) & {
42
+ unexpectedError?: AllowedUnexpectedErrorPolicy<TEvent>;
43
+ };
44
+ type PreToolUseResult = PreToolUseOutput | undefined;
45
+ type PostToolUseResult = PostToolUseOutput | undefined;
46
+ type PreInvocationResult = PreInvocationOutput | undefined;
47
+ type PostInvocationResult = PostInvocationOutput | undefined;
48
+ type StopResult = StopOutput | undefined;
49
+ /**
50
+ * A bound Antigravity hook: the wrapped handler plus its driver metadata.
51
+ * Carries both `hookEventName` (this surface's historical property name)
52
+ * and `eventName` (the core driver's property), identical values.
53
+ * @template TInput - The input type for this hook
54
+ * @template TOutput - The output type for this hook
55
+ * @template TEvent - The literal event name this hook is bound to
56
+ */
57
+ export interface HookFunction<TInput, TOutput, TEvent extends string> {
58
+ (input: TInput, context: HookContext): Promise<TOutput | null>;
59
+ hookEventName: TEvent;
60
+ eventName: string;
61
+ matcher?: string;
62
+ timeout?: number;
63
+ unexpectedError?: UnexpectedErrorPolicy;
64
+ onUnexpectedError?: UnexpectedErrorHandler;
65
+ createContext?: (input: TInput) => HookContext;
66
+ }
67
+ /** Creates a PreToolUse hook handler. */
68
+ export declare function preToolUseHook(config: HookConfigFor<"PreToolUse">, handler: (input: PreToolUseInput, context: HookContext) => PreToolUseResult | Promise<PreToolUseResult>): HookFunction<PreToolUseInput, PreToolUseResult, "PreToolUse">;
69
+ /** Creates a PostToolUse hook handler. */
70
+ export declare function postToolUseHook(config: HookConfigFor<"PostToolUse">, handler: (input: PostToolUseInput, context: HookContext) => PostToolUseResult | Promise<PostToolUseResult>): HookFunction<PostToolUseInput, PostToolUseResult, "PostToolUse">;
71
+ /** Creates a PreInvocation hook handler. */
72
+ export declare function preInvocationHook(config: HookConfigFor<"PreInvocation">, handler: (input: PreInvocationInput, context: HookContext) => PreInvocationResult | Promise<PreInvocationResult>): HookFunction<PreInvocationInput, PreInvocationResult, "PreInvocation">;
73
+ /** Creates a PostInvocation hook handler. */
74
+ export declare function postInvocationHook(config: HookConfigFor<"PostInvocation">, handler: (input: PostInvocationInput, context: HookContext) => PostInvocationResult | Promise<PostInvocationResult>): HookFunction<PostInvocationInput, PostInvocationResult, "PostInvocation">;
75
+ /** Creates a Stop hook handler. */
76
+ export declare function stopHook(config: HookConfigFor<"Stop">, handler: (input: StopInput, context: HookContext) => StopResult | Promise<StopResult>): HookFunction<StopInput, StopResult, "Stop">;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `@goodfoot/agent-hooks/antigravity` — the Antigravity agent surface.
3
+ *
4
+ * **Not yet published as a package subpath.** Step 5 ships under its item-6
5
+ * descope (Step 0 concluded "not runnable / unknown" for the real
6
+ * `antigravity` CLI in this release's environment): typed factories, output
7
+ * builders, and a conformance matrix only. `packages/agent-hooks/package.json`
8
+ * deliberately does not add a `./antigravity` `exports` entry this release —
9
+ * see `tests/export-surface.test.ts`, which asserts the exports map stays
10
+ * closed at `.`/`./claude-code`/`./codex`. This module exists for in-repo
11
+ * testing (the conformance matrix imports it directly by relative path) and
12
+ * for the follow-up card that resolves the CLI-availability question to
13
+ * build on without re-deriving the surface from scratch.
14
+ *
15
+ * Re-exports the 5 hook factories, their output builders (reserved fields
16
+ * emitted only when passed), the `AntigravityBlockError` block signal,
17
+ * input/output types, and the runtime `execute` entry point. No default
18
+ * export.
19
+ * @module
20
+ */
21
+ export type { AdvisoryEventName, AllowedUnexpectedErrorPolicy, ExcludedEventName, IsExcludedEvent, } from "./events.js";
22
+ export { ADVISORY_EVENTS, EVENTS_WITH_MATCHER, EXCLUDED_FROM_ADVISORY, HOOK_EVENT_NAMES } from "./events.js";
23
+ export type { HookConfig, HookConfigFor, HookContext, HookFunction, UnexpectedErrorHandler, UnexpectedErrorPolicy, } from "./hooks.js";
24
+ export { postInvocationHook, postToolUseHook, preInvocationHook, preToolUseHook, stopHook } from "./hooks.js";
25
+ export { AntigravityBlockError, type AntigravityDecision, type AntigravityHookOutput, type AntigravityPostDecision, EXIT_CODES, type ExitCode, type HookOutput, type PostInvocationOptions, type PostInvocationOutput, type PostToolUseOptions, type PostToolUseOutput, type PreInvocationOptions, type PreInvocationOutput, type PreToolUseOptions, type PreToolUseOutput, postInvocationOutput, postToolUseOutput, preInvocationOutput, preToolUseOutput, type SpecificHookOutput, type StopOptions, type StopOutput, stopOutput, } from "./outputs.js";
26
+ export { createAntigravityTransport, execute } from "./transport.js";
27
+ export type { BaseHookInput, HookErrorPhase, HookEventName, HookInput, PostInvocationInput, PostToolUseInput, PreInvocationInput, PreToolUseInput, StopInput, } from "./types.js";
@@ -0,0 +1,107 @@
1
+ import { HookBlockError } from "../../core/transport.js";
2
+ /**
3
+ * Antigravity has no exit-code signaling channel: every event replies at
4
+ * exit 0 and every decision — allow, deny, or ask — is expressed inside the
5
+ * JSON payload. `EXIT_CODES.SUCCESS` is the only member for that reason; see
6
+ * `transport.ts`'s module docs for the consequence this has for
7
+ * {@link AntigravityBlockError}.
8
+ */
9
+ export declare const EXIT_CODES: {
10
+ readonly SUCCESS: 0;
11
+ };
12
+ export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
13
+ /**
14
+ * The full permission-decision vocabulary a `PreToolUse` handler may return,
15
+ * derived structurally from Codex's narrower `PreToolUsePermissionDecision`
16
+ * (`"allow" | "deny" | "ask"`) plus the two additional values the plan names
17
+ * verbatim (`force_ask`, `deny_unless_prior_grant`) with no further doc to
18
+ * cite this release:
19
+ *
20
+ * - `force_ask` — like `ask`, but the handler is asserting the host may not
21
+ * auto-resolve this prompt from a prior grant even if one would otherwise
22
+ * apply;
23
+ * - `deny_unless_prior_grant` — deny unless the host already holds a prior
24
+ * grant covering this exact call.
25
+ */
26
+ export type AntigravityDecision = "allow" | "deny" | "ask" | "force_ask" | "deny_unless_prior_grant";
27
+ /** The narrower decision vocabulary available after a tool has already run. */
28
+ export type AntigravityPostDecision = Extract<AntigravityDecision, "allow" | "deny">;
29
+ interface BaseSpecificOutput<T extends string> {
30
+ readonly _type: T;
31
+ readonly stdout: AntigravityHookOutput;
32
+ }
33
+ export type PreToolUseOutput = BaseSpecificOutput<"PreToolUse">;
34
+ export type PostToolUseOutput = BaseSpecificOutput<"PostToolUse">;
35
+ export type PreInvocationOutput = BaseSpecificOutput<"PreInvocation">;
36
+ export type PostInvocationOutput = BaseSpecificOutput<"PostInvocation">;
37
+ export type StopOutput = BaseSpecificOutput<"Stop">;
38
+ export type SpecificHookOutput = PreToolUseOutput | PostToolUseOutput | PreInvocationOutput | PostInvocationOutput | StopOutput;
39
+ /**
40
+ * The wire shape every event's stdout carries. Termination is expressed the
41
+ * same payload-only way a decision is: `stop: true` asks the host to end the
42
+ * session, there being no separate exit-code channel to carry that signal.
43
+ */
44
+ export interface AntigravityHookOutput {
45
+ decision?: AntigravityDecision;
46
+ reason?: string;
47
+ additionalContext?: string;
48
+ updatedInput?: unknown;
49
+ stop?: boolean;
50
+ systemMessage?: string;
51
+ }
52
+ export interface HookOutput {
53
+ stdout: AntigravityHookOutput;
54
+ }
55
+ export interface PreToolUseOptions {
56
+ decision?: AntigravityDecision;
57
+ reason?: string;
58
+ additionalContext?: string;
59
+ updatedInput?: unknown;
60
+ systemMessage?: string;
61
+ }
62
+ export interface PostToolUseOptions {
63
+ decision?: AntigravityPostDecision;
64
+ reason?: string;
65
+ additionalContext?: string;
66
+ systemMessage?: string;
67
+ }
68
+ export interface PreInvocationOptions {
69
+ decision?: Extract<AntigravityDecision, "allow" | "deny" | "ask">;
70
+ reason?: string;
71
+ additionalContext?: string;
72
+ systemMessage?: string;
73
+ }
74
+ export interface PostInvocationOptions {
75
+ additionalContext?: string;
76
+ systemMessage?: string;
77
+ }
78
+ export interface StopOptions {
79
+ stop?: boolean;
80
+ reason?: string;
81
+ systemMessage?: string;
82
+ }
83
+ /**
84
+ * The Antigravity block signal, carried as a subclass of the shared core
85
+ * {@link ../../core/transport.ts|HookBlockError} so `drive()` classifies it
86
+ * **before** consulting `unexpectedError` policy — exactly mirroring Claude
87
+ * Code's `HookBlockError` usage and Codex's `BlockError` re-export.
88
+ *
89
+ * This mechanism is a stated *prerequisite*, not a follow-up, for
90
+ * Antigravity specifically: because every Antigravity event replies at exit
91
+ * 0 with the decision expressed only in the JSON payload (Research, plan
92
+ * Step 5), a handler that throws mid-decision has no narrower exit-code
93
+ * fallback to land on the way Codex's stderr+exit-2 channel does — the block
94
+ * decision would otherwise be indistinguishable from a swallowed crash. This
95
+ * class landing is what makes it safe to ever widen `events.ts`'s advisory
96
+ * allow-list past empty.
97
+ */
98
+ export declare class AntigravityBlockError extends HookBlockError {
99
+ readonly reason: string;
100
+ constructor(reason: string);
101
+ }
102
+ export declare function preToolUseOutput(options?: PreToolUseOptions): PreToolUseOutput;
103
+ export declare function postToolUseOutput(options?: PostToolUseOptions): PostToolUseOutput;
104
+ export declare function preInvocationOutput(options?: PreInvocationOptions): PreInvocationOutput;
105
+ export declare function postInvocationOutput(options?: PostInvocationOptions): PostInvocationOutput;
106
+ export declare function stopOutput(options?: StopOptions): StopOutput;
107
+ export {};
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Wire transport for Antigravity hooks, built against the core
3
+ * `drive()`/`Transport` interface — the same seam Claude Code's and Codex's
4
+ * transports are rewritten/re-exported against.
5
+ *
6
+ * Antigravity's wire semantics are the simplest of the three shipped agents,
7
+ * and also the least forgiving: **every reply exits 0, unconditionally.**
8
+ * There is no exit-code channel at all — not the 2-of-30-events native-deny
9
+ * split Claude Code has, not Codex's uniform stderr+exit-2 `BlockError`
10
+ * channel. Every decision (allow/deny/ask and its finer variants) and every
11
+ * unexpected-failure diagnostic lives inside the JSON stdout payload:
12
+ *
13
+ * - success → `JSON.stringify(output.stdout)` at exit 0; `null`/`undefined`
14
+ * serializes as `{}`.
15
+ * - a caught {@link AntigravityBlockError} → `{ decision: "deny", reason,
16
+ * ...fields }` on stdout at exit 0 — this is why the class is a stated
17
+ * prerequisite (`outputs.ts` module docs, `events.ts` module docs): with no
18
+ * exit-code fallback, a block computed mid-throw has nowhere else to land.
19
+ * - an unexpected handler/runtime failure → its stacktrace on stderr
20
+ * (diagnostic only, not a wire signal) plus the empty response `{}` on
21
+ * stdout, still at exit 0.
22
+ * @module
23
+ * @example
24
+ * ```typescript
25
+ * // In a compiled hook file
26
+ * import { execute } from './transport.js';
27
+ * import myHook from './my-hook.js';
28
+ *
29
+ * execute(myHook);
30
+ * ```
31
+ */
32
+ import type { Transport } from "../../core/transport.js";
33
+ import type { HookFunction } from "./hooks.js";
34
+ import { type SpecificHookOutput } from "./outputs.js";
35
+ import type { HookEventName, HookInput } from "./types.js";
36
+ /**
37
+ * Builds the Antigravity wire transport. Every branch returns
38
+ * `exitCode: EXIT_CODES.SUCCESS` — see module docs — so the only thing that
39
+ * varies per outcome is what lands on stdout (the machine-readable payload)
40
+ * versus stderr (a diagnostic no host is asserted to read).
41
+ */
42
+ export declare function createAntigravityTransport(): Transport<SpecificHookOutput | undefined>;
43
+ /**
44
+ * Executes a hook handler with full runtime orchestration (delegates to the
45
+ * shared core driver with this agent's transport).
46
+ */
47
+ export declare function execute<TInput extends HookInput, TOutput>(hookFn: HookFunction<TInput, TOutput, HookEventName>): Promise<void>;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Antigravity wire types (plan step 5, item-6 descope: typed factories +
3
+ * output builders + conformance matrix only — no `CONTRACT.md` pin, no
4
+ * published protocol doc exists for this release). Shapes below are the
5
+ * minimal surface the plan names for the five shipped events
6
+ * (`PreToolUse`/`PostToolUse`/`PreInvocation`/`PostInvocation`/`Stop`),
7
+ * derived structurally from Claude Code's and Codex's `types.ts` rather than
8
+ * from any Antigravity-specific reference — there is none to cite yet.
9
+ * @module
10
+ */
11
+ export type HookEventName = "PreToolUse" | "PostToolUse" | "PreInvocation" | "PostInvocation" | "Stop";
12
+ export interface BaseHookInput {
13
+ cwd: string;
14
+ hook_event_name: HookEventName;
15
+ session_id: string;
16
+ }
17
+ export interface PreToolUseInput extends BaseHookInput {
18
+ hook_event_name: "PreToolUse";
19
+ tool_name: string;
20
+ tool_input: unknown;
21
+ }
22
+ export interface PostToolUseInput extends BaseHookInput {
23
+ hook_event_name: "PostToolUse";
24
+ tool_name: string;
25
+ tool_input: unknown;
26
+ tool_response: unknown;
27
+ }
28
+ export interface PreInvocationInput extends BaseHookInput {
29
+ hook_event_name: "PreInvocation";
30
+ prompt: string;
31
+ }
32
+ export interface PostInvocationInput extends BaseHookInput {
33
+ hook_event_name: "PostInvocation";
34
+ response: string | null;
35
+ }
36
+ export interface StopInput extends BaseHookInput {
37
+ hook_event_name: "Stop";
38
+ last_assistant_message: string | null;
39
+ }
40
+ export type HookInput = PreToolUseInput | PostToolUseInput | PreInvocationInput | PostInvocationInput | StopInput;
41
+ /**
42
+ * "error" (default) surfaces an unexpected runtime failure through the
43
+ * transport's stderr diagnostic channel (see `transport.ts` — Antigravity has
44
+ * no exit-code channel at all, so this never changes the process exit code).
45
+ *
46
+ * "continue" would swallow an unexpected failure into the event's empty
47
+ * response. No event currently accepts it: {@link EXCLUDED_FROM_ADVISORY | the
48
+ * advisory allow-list} in `events.ts` defaults to every event until a future
49
+ * `CONTRACT.md` names an enrichment hook safe to opt in.
50
+ */
51
+ export type UnexpectedErrorPolicy = "error" | "continue";
52
+ /** The runtime phase in which an unexpected error occurred. */
53
+ export type HookErrorPhase = "read" | "parse" | "handler" | "serialize" | "write" | "cleanup";
54
+ /**
55
+ * Best-effort diagnostic sink for unexpected errors under the "continue"
56
+ * policy. Errors thrown by this handler are swallowed.
57
+ */
58
+ export type UnexpectedErrorHandler = (error: unknown, phase: HookErrorPhase) => void;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Environment variable utilities for Claude Code hooks.
3
+ *
4
+ * The implementation lives in the committed core (`../../core/env.ts`), which
5
+ * is a byte-for-byte port of `claude-code-hooks/src/env.ts`; this module is
6
+ * the per-agent import site so the Claude Code surface keeps its historical
7
+ * `env.js` path on the barrel.
8
+ * @module
9
+ * @example
10
+ * ```typescript
11
+ * import { getProjectDir, persistEnvVar, isRemoteEnvironment } from '@goodfoot/agent-hooks/claude-code';
12
+ *
13
+ * // Get project directory
14
+ * const projectDir = getProjectDir();
15
+ *
16
+ * // Check if running remotely
17
+ * if (isRemoteEnvironment()) {
18
+ * // Handle remote-specific logic
19
+ * }
20
+ *
21
+ * // In SessionStart hook: persist environment variables
22
+ * persistEnvVar('NODE_ENV', 'production');
23
+ * persistEnvVar('API_KEY', 'secret-key');
24
+ * ```
25
+ * @see https://code.claude.com/docs/en/hooks#hook-execution-details
26
+ */
27
+ export { CLAUDE_ENV_VARS, getEnvFilePath, getProjectDir, isRemoteEnvironment, persistEnvVar, persistEnvVars, } from "../../core/env.js";
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Claude Code hook event names and the advisory fail-open allow-list.
3
+ *
4
+ * `HOOK_EVENT_NAMES` is copied verbatim from `claude-code-hooks/src/types.ts`
5
+ * (all 30 events, same order). The advisory allow-list is **not** authored
6
+ * here: per the plan's derivation rule it is transcribed from CARD.md:75 —
7
+ * quoted below above `EXCLUDED_FROM_ADVISORY` — and `ADVISORY_EVENTS` is
8
+ * derived mechanically as "every event except the exclusion set". The unit
9
+ * test in `tests/agents/claude-code/` transcribes the same sentence a second
10
+ * time, independently, so the runtime list and the test oracle are two
11
+ * copies of the citation rather than one list read twice.
12
+ * @module
13
+ */
14
+ import type { UnexpectedErrorPolicy } from "../../core/types.js";
15
+ import type { HookEventName } from "./types.js";
16
+ /**
17
+ * All Claude Code hook event names as a readonly array.
18
+ *
19
+ * Useful for iteration and validation.
20
+ * @example
21
+ * ```typescript
22
+ * for (const eventName of HOOK_EVENT_NAMES) {
23
+ * console.log(`Supported hook: ${eventName}`);
24
+ * }
25
+ * ```
26
+ */
27
+ export declare const HOOK_EVENT_NAMES: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "Notification", "UserPromptExpansion", "UserPromptSubmit", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact", "PermissionRequest", "PermissionDenied", "Setup", "TeammateIdle", "TaskCreated", "TaskCompleted", "Elicitation", "ElicitationResult", "ConfigChange", "InstructionsLoaded", "WorktreeCreate", "WorktreeRemove", "CwdChanged", "FileChanged", "MessageDisplay"];
28
+ /**
29
+ * Events never allowed the fail-open `unexpectedError: "continue"` policy.
30
+ *
31
+ * Transcribed verbatim from CARD.md:75:
32
+ *
33
+ * > `unexpectedError: "continue"` is rejected at the type level and at
34
+ * > runtime for any event not on that agent's advisory list (never
35
+ * > `PreToolUse`, `PermissionRequest`, blocking `Stop`/`SubagentStop`,
36
+ * > `WorktreeCreate`/`WorktreeRemove` on Claude Code; ...).
37
+ *
38
+ * The first five refuse because a swallowed failure silently grants the very
39
+ * decision the hook was supposed to make; the worktree pair additionally
40
+ * speaks a plain-text stdout protocol with no safe generic fallback, so a
41
+ * swallowed failure would write literal `{}` where the host expects a path.
42
+ */
43
+ export declare const EXCLUDED_FROM_ADVISORY: readonly ["PreToolUse", "PermissionRequest", "Stop", "SubagentStop", "WorktreeCreate", "WorktreeRemove"];
44
+ /**
45
+ * Type-level membership check for the advisory allow-list.
46
+ *
47
+ * Resolves to `true` only for event names excluded from the allow-list.
48
+ */
49
+ export type IsExcludedEvent<TEventName extends HookEventName> = TEventName extends ExcludedEventName ? true : false;
50
+ /** The exclusion set as a literal union. */
51
+ export type ExcludedEventName = (typeof EXCLUDED_FROM_ADVISORY)[number];
52
+ /** The advisory allow-list as a literal union: every event except {@link ExcludedEventName}. */
53
+ export type AdvisoryEventName = Exclude<HookEventName, ExcludedEventName>;
54
+ /**
55
+ * The advisory allow-list: every Claude Code event except
56
+ * {@link EXCLUDED_FROM_ADVISORY}. Only these events accept
57
+ * `unexpectedError: "continue"` — enforced at factory-call time by the
58
+ * policy gate injected into {@link ../core/define-hook.ts|defineHook} and at
59
+ * compile time by the excluded events' narrowed config types.
60
+ */
61
+ export declare const ADVISORY_EVENTS: readonly AdvisoryEventName[];
62
+ /**
63
+ * The policy type an event may carry, narrowed by allow-list membership.
64
+ *
65
+ * Advisory events keep the full `"error" | "continue"` union; every excluded
66
+ * event collapses to `"error"`, so passing `"continue"` there is rejected at
67
+ * compile time (and again at factory-call time by the runtime gate).
68
+ */
69
+ export type AllowedUnexpectedErrorPolicy<TEventName extends HookEventName> = IsExcludedEvent<TEventName> extends true ? Exclude<UnexpectedErrorPolicy, "continue"> : UnexpectedErrorPolicy;