@goodfoot/agent-hooks 1.0.7 → 1.0.9

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.
@@ -1,37 +1,39 @@
1
1
  /**
2
- * Antigravity hook event names and the (currently empty) advisory allow-list.
2
+ * Antigravity hook event names, the grouped/flat structural split, and the
3
+ * (empty) advisory allow-list.
3
4
  *
4
- * Unlike Claude Code's and Codex's allow-lists, which transcribe a named set
5
- * of enrichment hooks out of a shipped README, Antigravity has no in-repo
6
- * doc to transcribe from this release (Step 0 descope — see the plan's Step
7
- * 5 blockquote). The allow-list therefore defaults to **every event
8
- * excluded**, not a curated subset, until a future card's `CONTRACT.md`
9
- * names a specific enrichment hook safe to opt into `unexpectedError:
10
- * "continue"`.
5
+ * The host's hook reference — pinned in this directory's `CONTRACT.md` —
6
+ * names five events and splits them structurally: `PreToolUse` and
7
+ * `PostToolUse` wrap their handlers in a `{ matcher, hooks }` group, while
8
+ * `PreInvocation`, `PostInvocation`, and `Stop` list handler objects
9
+ * directly and ignore any matcher. {@link EVENTS_WITH_MATCHER} is that split,
10
+ * and `cli-support.ts` emits `hooks.json` from it.
11
11
  *
12
- * That default is itself gated on a second precondition: because Antigravity
13
- * has no exit-code channel at all (every event is payload-only — see
14
- * `transport.ts` and `outputs.ts`'s {@link AntigravityBlockError}), a
15
- * fail-open swallow on this agent has no narrower fallback than Claude
16
- * Code's or Codex's — there is no stderr+exit-2 loud path to fall back to.
17
- * `AntigravityBlockError` landing first (this same step) is what makes it
18
- * safe to ever widen this list at all: an intentional block computed
19
- * mid-throw still survives `unexpectedError: "continue"` via `drive()`'s
20
- * pre-policy classification, exactly as it does for the other two agents.
12
+ * The advisory allow-list is empty, and stays empty: the reference names no
13
+ * event as safe to fail open. That default is load-bearing here in a way it
14
+ * is not on the other two agents, because Antigravity has no exit-code
15
+ * channel at all (every event is payload-only — see `transport.ts` and
16
+ * `outputs.ts`'s {@link AntigravityBlockError}), so a fail-open swallow has
17
+ * no loud path to degrade to. `AntigravityBlockError` is what would make
18
+ * widening the list safe at all: an intentional block computed mid-throw
19
+ * still survives `unexpectedError: "continue"` via `drive()`'s pre-policy
20
+ * classification, exactly as it does for the other two agents.
21
21
  * @module
22
22
  */
23
23
  import type { UnexpectedErrorPolicy } from "../../core/types.js";
24
24
  import type { HookEventName } from "./types.js";
25
25
  /** All Antigravity hook event names as a readonly array. */
26
26
  export declare const HOOK_EVENT_NAMES: readonly ["PreToolUse", "PostToolUse", "PreInvocation", "PostInvocation", "Stop"];
27
- /** The two events whose config accepts a `matcher` (plan step 5.3: "matcher on the two ToolUse events"). */
27
+ /**
28
+ * The two events whose `hooks.json` entry is grouped under a `matcher`. The
29
+ * other three are flat: the host ignores a matcher on them entirely.
30
+ */
28
31
  export declare const EVENTS_WITH_MATCHER: readonly HookEventName[];
29
32
  /**
30
33
  * Events never allowed the fail-open `unexpectedError: "continue"` policy.
31
34
  *
32
- * Every shipped event, by default — see module docs. This is a stated
33
- * default (plan Decisions: "advisory list default empty until CONTRACT.md
34
- * justifies an entry"), not a silent gap.
35
+ * Every shipped event. The host's hook reference names no event as safe to
36
+ * fail open, so this is a transcribed conclusion, not a placeholder.
35
37
  */
36
38
  export declare const EXCLUDED_FROM_ADVISORY: readonly ["PreToolUse", "PostToolUse", "PreInvocation", "PostInvocation", "Stop"];
37
39
  /** The exclusion set as a literal union. Currently every event. */
@@ -40,7 +42,7 @@ export type ExcludedEventName = (typeof EXCLUDED_FROM_ADVISORY)[number];
40
42
  export type IsExcludedEvent<TEventName extends HookEventName> = TEventName extends ExcludedEventName ? true : false;
41
43
  /** The advisory allow-list as a literal union: every event except {@link ExcludedEventName} — currently `never`. */
42
44
  export type AdvisoryEventName = Exclude<HookEventName, ExcludedEventName>;
43
- /** The advisory allow-list. Empty until a future `CONTRACT.md` names an entry. */
45
+ /** The advisory allow-list. Empty: `CONTRACT.md` names no event safe to fail open. */
44
46
  export declare const ADVISORY_EVENTS: readonly AdvisoryEventName[];
45
47
  /**
46
48
  * The policy type an event may carry, narrowed by allow-list membership.
@@ -2,20 +2,19 @@
2
2
  * Typed factory functions for Antigravity hooks, built on the shared core
3
3
  * {@link ../../core/define-hook.ts|defineHook}.
4
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.
5
+ * Every factory injects the advisory allow-list policy gate, so
6
+ * `unexpectedError: "continue"` fails closed at factory-call time for every
7
+ * event ({@link ADVISORY_EVENTS} is empty, and `CONTRACT.md` names no event
8
+ * safe to fail open); {@link HookConfigFor} additionally narrows the policy
9
+ * field at compile time.
12
10
  *
13
11
  * Antigravity's config surface is a single conditional type rather than the
14
12
  * separate matcher/no-matcher interface pair Claude Code and Codex use: only
15
13
  * two of the five events (`PreToolUse`, `PostToolUse`) carry a `matcher`
16
14
  * ({@link EVENTS_WITH_MATCHER} in `events.ts`), and a conditional type on the
17
15
  * bound event expresses that distinction without duplicating the base field
18
- * list twice.
16
+ * list twice. The host ignores a matcher on the other three events entirely,
17
+ * so accepting one there would be a silent no-op.
19
18
  * @module
20
19
  */
21
20
  import type { HookContext, UnexpectedErrorHandler, UnexpectedErrorPolicy } from "../../core/types.js";
@@ -1,27 +1,20 @@
1
1
  /**
2
2
  * `@goodfoot/agent-hooks/antigravity` — the Antigravity agent surface.
3
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.
4
+ * Re-exports the five hook factories, their per-event output builders, the
5
+ * `AntigravityBlockError` block signal, the wire input/output types, and the
6
+ * runtime `execute` entry point. No default export.
14
7
  *
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.
8
+ * Every shape here is transcribed from `CONTRACT.md` in this directory, which
9
+ * pins the host's own hook reference. Two consequences shape the whole
10
+ * surface: keys are camelCase, and each event has a **different** stdout
11
+ * shape rather than one shared envelope.
19
12
  * @module
20
13
  */
21
14
  export type { AdvisoryEventName, AllowedUnexpectedErrorPolicy, ExcludedEventName, IsExcludedEvent, } from "./events.js";
22
15
  export { ADVISORY_EVENTS, EVENTS_WITH_MATCHER, EXCLUDED_FROM_ADVISORY, HOOK_EVENT_NAMES } from "./events.js";
23
16
  export type { HookConfig, HookConfigFor, HookContext, HookFunction, UnexpectedErrorHandler, UnexpectedErrorPolicy, } from "./hooks.js";
24
17
  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";
18
+ export { AntigravityBlockError, type AntigravityDecision, type AntigravityHookOutput, EXIT_CODES, type ExitCode, type HookOutput, type InjectStep, type PostInvocationOptions, type PostInvocationOutput, type PostInvocationStdout, type PostToolUseOutput, type PostToolUseStdout, type PreInvocationOptions, type PreInvocationOutput, type PreInvocationStdout, type PreToolUseOptions, type PreToolUseOutput, type PreToolUseStdout, postInvocationOutput, postToolUseOutput, preInvocationOutput, preToolUseOutput, type SpecificHookOutput, type StopDecision, type StopOptions, type StopOutput, type StopStdout, stopOutput, type TerminationBehavior, } from "./outputs.js";
26
19
  export { createAntigravityTransport, execute } from "./transport.js";
27
- export type { BaseHookInput, HookErrorPhase, HookEventName, HookInput, PostInvocationInput, PostToolUseInput, PreInvocationInput, PreToolUseInput, StopInput, } from "./types.js";
20
+ export type { AntigravityToolCall, BaseHookInput, HookErrorPhase, HookEventName, HookInput, PostInvocationInput, PostToolUseInput, PreInvocationInput, PreToolUseInput, StopInput, } from "./types.js";
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Antigravity output builders, one per event.
3
+ *
4
+ * Unlike Claude Code and Codex, Antigravity gives each event a **different**
5
+ * stdout shape — there is no single envelope every event shares. `PreToolUse`
6
+ * returns a permission decision, `PostToolUse` returns `{}` and nothing else,
7
+ * the two invocation events return injected steps, and `Stop` returns a
8
+ * continue-or-not decision. Each builder below emits only the fields its own
9
+ * event's contract names; see `CONTRACT.md` in this directory.
10
+ * @module
11
+ */
1
12
  import { HookBlockError } from "../../core/transport.js";
2
13
  /**
3
14
  * Antigravity has no exit-code signaling channel: every event replies at
@@ -11,97 +22,115 @@ export declare const EXIT_CODES: {
11
22
  };
12
23
  export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
13
24
  /**
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:
25
+ * The `PreToolUse` permission vocabulary, verbatim from the host reference:
19
26
  *
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.
27
+ * - `allow` — run the tool without prompting;
28
+ * - `deny` — hard block the execution immediately;
29
+ * - `ask` — prompt the user, respecting the "Always Allow" cache;
30
+ * - `force_ask` — always prompt, ignoring cached permissions.
31
+ *
32
+ * There is no fifth value. An earlier draft of this surface carried
33
+ * `deny_unless_prior_grant`; the host reference does not define it, and the
34
+ * host would treat it as an unrecognized decision.
25
35
  */
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;
36
+ export type AntigravityDecision = "allow" | "deny" | "ask" | "force_ask";
39
37
  /**
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.
38
+ * The `Stop` decision. `"continue"` blocks the stop and re-enters the loop;
39
+ * any other value lets the agent stop, so `"stop"` is spelled explicitly here
40
+ * rather than left to an omitted field.
43
41
  */
44
- export interface AntigravityHookOutput {
42
+ export type StopDecision = "continue" | "stop";
43
+ /** How the host should treat loop termination after `PostInvocation`. */
44
+ export type TerminationBehavior = "force_continue" | "terminate" | "";
45
+ /**
46
+ * A step injected by `PreInvocation` or `PostInvocation`. Exactly one of the
47
+ * three forms per entry.
48
+ */
49
+ export type InjectStep = {
50
+ toolCall: {
51
+ name: string;
52
+ args: Record<string, unknown>;
53
+ };
54
+ } | {
55
+ userMessage: string;
56
+ } | {
57
+ ephemeralMessage: string;
58
+ };
59
+ /** `PreToolUse` stdout. */
60
+ export interface PreToolUseStdout {
45
61
  decision?: AntigravityDecision;
46
62
  reason?: string;
47
- additionalContext?: string;
48
- updatedInput?: unknown;
49
- stop?: boolean;
50
- systemMessage?: string;
51
- }
52
- export interface HookOutput {
53
- stdout: AntigravityHookOutput;
63
+ permissionOverrides?: string[];
64
+ overwrite?: Record<string, unknown>;
54
65
  }
55
- export interface PreToolUseOptions {
56
- decision?: AntigravityDecision;
57
- reason?: string;
58
- additionalContext?: string;
59
- updatedInput?: unknown;
60
- systemMessage?: string;
66
+ /** `PostToolUse` stdout: the contract specifies an empty object and nothing else. */
67
+ export type PostToolUseStdout = Record<string, never>;
68
+ /** `PreInvocation` stdout. */
69
+ export interface PreInvocationStdout {
70
+ injectSteps?: InjectStep[];
61
71
  }
62
- export interface PostToolUseOptions {
63
- decision?: AntigravityPostDecision;
64
- reason?: string;
65
- additionalContext?: string;
66
- systemMessage?: string;
72
+ /** `PostInvocation` stdout. */
73
+ export interface PostInvocationStdout {
74
+ injectSteps?: InjectStep[];
75
+ terminationBehavior?: TerminationBehavior;
67
76
  }
68
- export interface PreInvocationOptions {
69
- decision?: Extract<AntigravityDecision, "allow" | "deny" | "ask">;
77
+ /** `Stop` stdout. */
78
+ export interface StopStdout {
79
+ decision?: StopDecision;
70
80
  reason?: string;
71
- additionalContext?: string;
72
- systemMessage?: string;
73
81
  }
74
- export interface PostInvocationOptions {
75
- additionalContext?: string;
76
- systemMessage?: string;
82
+ interface BaseSpecificOutput<TType extends string, TStdout> {
83
+ readonly _type: TType;
84
+ readonly stdout: TStdout;
77
85
  }
78
- export interface StopOptions {
79
- stop?: boolean;
80
- reason?: string;
81
- systemMessage?: string;
86
+ export type PreToolUseOutput = BaseSpecificOutput<"PreToolUse", PreToolUseStdout>;
87
+ export type PostToolUseOutput = BaseSpecificOutput<"PostToolUse", PostToolUseStdout>;
88
+ export type PreInvocationOutput = BaseSpecificOutput<"PreInvocation", PreInvocationStdout>;
89
+ export type PostInvocationOutput = BaseSpecificOutput<"PostInvocation", PostInvocationStdout>;
90
+ export type StopOutput = BaseSpecificOutput<"Stop", StopStdout>;
91
+ export type SpecificHookOutput = PreToolUseOutput | PostToolUseOutput | PreInvocationOutput | PostInvocationOutput | StopOutput;
92
+ /** The union of every event's stdout shape. */
93
+ export type AntigravityHookOutput = PreToolUseStdout | PostToolUseStdout | PreInvocationStdout | PostInvocationStdout | StopStdout;
94
+ export interface HookOutput {
95
+ stdout: AntigravityHookOutput;
82
96
  }
97
+ export type PreToolUseOptions = PreToolUseStdout;
98
+ export type PreInvocationOptions = PreInvocationStdout;
99
+ export type PostInvocationOptions = PostInvocationStdout;
100
+ export type StopOptions = StopStdout;
83
101
  /**
84
102
  * The Antigravity block signal, carried as a subclass of the shared core
85
103
  * {@link ../../core/transport.ts|HookBlockError} so `drive()` classifies it
86
104
  * **before** consulting `unexpectedError` policy — exactly mirroring Claude
87
105
  * Code's `HookBlockError` usage and Codex's `BlockError` re-export.
88
106
  *
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.
107
+ * The class matters more here than on the other two agents: because every
108
+ * Antigravity event replies at exit 0 with the decision expressed only in the
109
+ * JSON payload, a handler that throws mid-decision has no narrower exit-code
110
+ * fallback to land on the way Codex's stderr+exit-2 channel does. Without
111
+ * this class the block would be indistinguishable from a swallowed crash.
112
+ *
113
+ * The transport serializes it as `{ "decision": "deny", ... }`, which the
114
+ * host acts on for `PreToolUse` only. On the other four events the reply is
115
+ * well-formed but carries no decision the host recognizes, so it reads as an
116
+ * empty response.
97
117
  */
98
118
  export declare class AntigravityBlockError extends HookBlockError {
99
119
  readonly reason: string;
100
120
  constructor(reason: string);
101
121
  }
122
+ /** Builds a `PreToolUse` reply: a permission decision, optionally with argument overwrites. */
102
123
  export declare function preToolUseOutput(options?: PreToolUseOptions): PreToolUseOutput;
103
- export declare function postToolUseOutput(options?: PostToolUseOptions): PostToolUseOutput;
124
+ /**
125
+ * Builds the `PostToolUse` reply. The contract defines the reply as an empty
126
+ * object, so this builder takes no options: there is nothing a `PostToolUse`
127
+ * handler can tell the host.
128
+ */
129
+ export declare function postToolUseOutput(): PostToolUseOutput;
130
+ /** Builds a `PreInvocation` reply carrying steps to inject before the model runs. */
104
131
  export declare function preInvocationOutput(options?: PreInvocationOptions): PreInvocationOutput;
132
+ /** Builds a `PostInvocation` reply: injected steps, a termination override, or both. */
105
133
  export declare function postInvocationOutput(options?: PostInvocationOptions): PostInvocationOutput;
134
+ /** Builds a `Stop` reply. `decision: "continue"` blocks the stop; `reason` is injected as a system message. */
106
135
  export declare function stopOutput(options?: StopOptions): StopOutput;
107
136
  export {};
@@ -0,0 +1,16 @@
1
+ import type { HookEventName } from "./types.js";
2
+ export interface ScaffoldOptions {
3
+ directory: string;
4
+ hooks: string[];
5
+ outputPath: string;
6
+ }
7
+ /** Resolves user-supplied hook names case-insensitively, rejecting the whole list on any miss. */
8
+ export declare function validateHookNames(requested: string[]): {
9
+ valid: true;
10
+ normalized: HookEventName[];
11
+ } | {
12
+ valid: false;
13
+ error: string;
14
+ };
15
+ /** Creates a new Antigravity hook project. Refuses to write into an existing directory. */
16
+ export declare function scaffoldProject(options: ScaffoldOptions): void;
@@ -3,7 +3,7 @@
3
3
  * `drive()`/`Transport` interface — the same seam Claude Code's and Codex's
4
4
  * transports are rewritten/re-exported against.
5
5
  *
6
- * Antigravity's wire semantics are the simplest of the three shipped agents,
6
+ * Antigravity's wire semantics are the simplest of the four shipped agents,
7
7
  * and also the least forgiving: **every reply exits 0, unconditionally.**
8
8
  * There is no exit-code channel at all — not the 2-of-30-events native-deny
9
9
  * split Claude Code has, not Codex's uniform stderr+exit-2 `BlockError`
@@ -16,6 +16,8 @@
16
16
  * ...fields }` on stdout at exit 0 — this is why the class is a stated
17
17
  * prerequisite (`outputs.ts` module docs, `events.ts` module docs): with no
18
18
  * exit-code fallback, a block computed mid-throw has nowhere else to land.
19
+ * The host acts on that decision for `PreToolUse`; on the other four events
20
+ * it is a well-formed reply carrying no decision the host recognizes.
19
21
  * - an unexpected handler/runtime failure → its stacktrace on stderr
20
22
  * (diagnostic only, not a wire signal) plus the empty response `{}` on
21
23
  * stdout, still at exit 0.
@@ -1,41 +1,68 @@
1
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.
2
+ * Antigravity wire types, transcribed from the host's own hook reference.
3
+ *
4
+ * Source of record: `assets/external/skills/agy-customizations/docs/hooks.md`,
5
+ * embedded in the `agy` binary and pinned verbatim in this directory's
6
+ * `CONTRACT.md`. Nothing here is derived by analogy from Claude Code or
7
+ * Codex — the three agents' payloads share no field.
8
+ *
9
+ * Two properties of this contract drive every shape below:
10
+ *
11
+ * 1. **All keys are camelCase** (protojson encoding), including `stepIdx` and
12
+ * `conversationId`.
13
+ * 2. **No payload carries its own event name.** Claude Code's
14
+ * `hook_event_name` and Codex's equivalent have no counterpart here; a
15
+ * handler knows its event only from the factory it was built with.
9
16
  * @module
10
17
  */
11
18
  export type HookEventName = "PreToolUse" | "PostToolUse" | "PreInvocation" | "PostInvocation" | "Stop";
19
+ /**
20
+ * System metadata present on every payload.
21
+ *
22
+ * `transcriptPath` and `artifactDirectoryPath` name a product-specific
23
+ * directory (`antigravity/`, `antigravity-cli/`, or `antigravity-ide/`
24
+ * depending on the interface), so neither may be pattern-matched.
25
+ */
12
26
  export interface BaseHookInput {
13
- cwd: string;
14
- hook_event_name: HookEventName;
15
- session_id: string;
27
+ conversationId: string;
28
+ workspacePaths: string[];
29
+ transcriptPath: string;
30
+ artifactDirectoryPath: string;
31
+ modelName: string;
32
+ }
33
+ /**
34
+ * A tool call as the host presents it. `name` is the step type lowercased with
35
+ * the `CORTEX_STEP_TYPE_` prefix removed — the same string a `matcher` regex
36
+ * is tested against.
37
+ */
38
+ export interface AntigravityToolCall {
39
+ name: string;
40
+ args: Record<string, unknown>;
16
41
  }
17
42
  export interface PreToolUseInput extends BaseHookInput {
18
- hook_event_name: "PreToolUse";
19
- tool_name: string;
20
- tool_input: unknown;
43
+ toolCall: AntigravityToolCall;
44
+ stepIdx: number;
21
45
  }
46
+ /** `error` is present only when the tool failed (e.g. `"exit status 1"`). */
22
47
  export interface PostToolUseInput extends BaseHookInput {
23
- hook_event_name: "PostToolUse";
24
- tool_name: string;
25
- tool_input: unknown;
26
- tool_response: unknown;
48
+ stepIdx: number;
49
+ error?: string;
27
50
  }
28
51
  export interface PreInvocationInput extends BaseHookInput {
29
- hook_event_name: "PreInvocation";
30
- prompt: string;
52
+ invocationNum: number;
53
+ initialNumSteps: number;
31
54
  }
55
+ /** Identical to {@link PreInvocationInput}; the host sends the same payload. */
32
56
  export interface PostInvocationInput extends BaseHookInput {
33
- hook_event_name: "PostInvocation";
34
- response: string | null;
57
+ invocationNum: number;
58
+ initialNumSteps: number;
35
59
  }
60
+ /** `terminationReason` is an open string — `"model_stop"`, `"max_steps_exceeded"`, `"error"`, and others. */
36
61
  export interface StopInput extends BaseHookInput {
37
- hook_event_name: "Stop";
38
- last_assistant_message: string | null;
62
+ executionNum: number;
63
+ terminationReason: string;
64
+ error?: string;
65
+ fullyIdle: boolean;
39
66
  }
40
67
  export type HookInput = PreToolUseInput | PostToolUseInput | PreInvocationInput | PostInvocationInput | StopInput;
41
68
  /**
@@ -44,9 +71,9 @@ export type HookInput = PreToolUseInput | PostToolUseInput | PreInvocationInput
44
71
  * no exit-code channel at all, so this never changes the process exit code).
45
72
  *
46
73
  * "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.
74
+ * response. No event accepts it: {@link EXCLUDED_FROM_ADVISORY | the advisory
75
+ * allow-list} in `events.ts` excludes every event, because the host's
76
+ * reference names no event as safe to fail open.
50
77
  */
51
78
  export type UnexpectedErrorPolicy = "error" | "continue";
52
79
  /** The runtime phase in which an unexpected error occurred. */
package/types/cli.d.ts CHANGED
@@ -28,7 +28,7 @@ type HookContext = "plugin" | "agent";
28
28
  * Command-line arguments parsed from process.argv.
29
29
  */
30
30
  interface CliArgs {
31
- /** Target agent runtime (required): "claude-code" | "codex" | "antigravity". */
31
+ /** Target agent runtime (required): "claude-code" | "codex" | "antigravity" | "opencode". */
32
32
  agent: string;
33
33
  /** Glob pattern for hook source files. */
34
34
  input: string;
package/types/index.d.ts CHANGED
@@ -6,8 +6,8 @@
6
6
  * {@link HookBlockError}, the Logger, env utilities, and stdin helpers.
7
7
  *
8
8
  * Per-agent entry points (`@goodfoot/agent-hooks/claude-code`, `/codex`,
9
- * `/antigravity`) are added to the package `exports` map only in the step
10
- * that lands their implementation — never pre-declared.
9
+ * `/opencode`, `/antigravity`) expose each host's native protocol without
10
+ * leaking host-specific types through this root module.
11
11
  * @module
12
12
  */
13
13
  export { defineHook } from "./core/define-hook.js";