@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.
- package/CHANGELOG.md +13 -0
- package/README.md +65 -34
- package/dist/agents/antigravity/cli-support.js +282 -0
- package/dist/agents/antigravity/constants.js +20 -0
- package/dist/agents/antigravity/events.js +24 -22
- package/dist/agents/antigravity/hooks.js +7 -8
- package/dist/agents/antigravity/index.js +7 -18
- package/dist/agents/antigravity/outputs.js +38 -31
- package/dist/agents/antigravity/scaffold.js +211 -0
- package/dist/agents/antigravity/transport.js +3 -1
- package/dist/agents/antigravity/types.js +14 -7
- package/dist/agents/codex/scaffold.js +1 -1
- package/dist/cli.js +61 -3
- package/dist/index.js +2 -2
- package/dist/scaffold.js +1 -1
- package/package.json +5 -1
- package/types/agents/antigravity/cli-support.d.ts +100 -0
- package/types/agents/antigravity/constants.d.ts +15 -0
- package/types/agents/antigravity/events.d.ts +24 -22
- package/types/agents/antigravity/hooks.d.ts +7 -8
- package/types/agents/antigravity/index.d.ts +9 -16
- package/types/agents/antigravity/outputs.d.ts +94 -65
- package/types/agents/antigravity/scaffold.d.ts +16 -0
- package/types/agents/antigravity/transport.d.ts +3 -1
- package/types/agents/antigravity/types.d.ts +53 -26
- package/types/cli.d.ts +1 -1
- package/types/index.d.ts +2 -2
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Antigravity hook event names
|
|
2
|
+
* Antigravity hook event names, the grouped/flat structural split, and the
|
|
3
|
+
* (empty) advisory allow-list.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
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
|
-
/**
|
|
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
|
|
33
|
-
*
|
|
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
|
|
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
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `
|
|
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
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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,
|
|
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
|
|
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
|
-
* - `
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* - `
|
|
24
|
-
*
|
|
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"
|
|
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
|
|
41
|
-
*
|
|
42
|
-
*
|
|
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
|
|
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
|
-
|
|
48
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
systemMessage?: string;
|
|
72
|
+
/** `PostInvocation` stdout. */
|
|
73
|
+
export interface PostInvocationStdout {
|
|
74
|
+
injectSteps?: InjectStep[];
|
|
75
|
+
terminationBehavior?: TerminationBehavior;
|
|
67
76
|
}
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
/** `Stop` stdout. */
|
|
78
|
+
export interface StopStdout {
|
|
79
|
+
decision?: StopDecision;
|
|
70
80
|
reason?: string;
|
|
71
|
-
additionalContext?: string;
|
|
72
|
-
systemMessage?: string;
|
|
73
81
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
interface BaseSpecificOutput<TType extends string, TStdout> {
|
|
83
|
+
readonly _type: TType;
|
|
84
|
+
readonly stdout: TStdout;
|
|
77
85
|
}
|
|
78
|
-
export
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
*
|
|
90
|
-
* Antigravity
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
tool_input: unknown;
|
|
26
|
-
tool_response: unknown;
|
|
48
|
+
stepIdx: number;
|
|
49
|
+
error?: string;
|
|
27
50
|
}
|
|
28
51
|
export interface PreInvocationInput extends BaseHookInput {
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
34
|
-
|
|
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
|
-
|
|
38
|
-
|
|
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
|
|
48
|
-
*
|
|
49
|
-
*
|
|
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`)
|
|
10
|
-
*
|
|
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";
|