/** * What Reticle says happened, and the shape it says it in. * * This is a CONTRACT, not an internal enum, which is why it lives in `core` beside the wire types. * A hook payload crosses into somebody else's script, so renaming an event kind is a breaking * change and has to be treated as one. * * Every event is a MOMENT SOMETHING BECAME TRUE, never a step on the way there. `verdict` is a * verdict; there is no `verdict_starting`, no `snapshot_taken`, no per-tool-call firehose — an event * that fires on internal progress freezes internal structure into a public contract. The bar for * adding one is the bar for a tool: name what a consumer could not otherwise know, and that stays * true if the implementation is rewritten. * * A payload carries NO credentials, ever — not the pairing token, not the cloud API key, not a * session cookie the page was carrying. Assume anything put here ends up in a log nobody here * controls. `hook-payload-carries-no-secret.test.ts` is the check, and it reads this file's schemas * rather than a hand-kept list. */ import { z } from 'zod'; /** * The events a hook can attach to. * * Values are the STRING a user writes in `.reticle/hooks.json`, so they read as English and stay * stable. A constant object rather than a TypeScript `enum` for the same reason as everything else * here: it survives `JSON.stringify` and a consumer can compare against the literal. */ export declare const HookEvent: { /** * A verdict landed — the thing this product exists to produce. * * Fires for ALL FOUR outcomes, `unknown` and `no-fault` included. A hook that only heard about * passes and failures would be told a different story from the one the verdict channel tells, and * "I could not tell" leaving the account is precisely the failure mode Reticle is built to stop. */ readonly VERDICT: "verdict"; /** * A defect was found. One event per defect, not one per run. * * Carries `repeat`, so a consumer can tell a newly-found defect from the same one seen again * without keeping its own ledger — counting instances as defects is how a number inflates itself. */ readonly BUG_FOUND: "bug_found"; /** A browser session attached. */ readonly SESSION_STARTED: "session_started"; /** A browser session ended, and its run artifact (if any) is on disk by the time this fires. */ readonly SESSION_ENDED: "session_ended"; /** * A cloud sync cycle finished, with what it actually moved. * * Fires on a cycle that sent NOTHING too. "Nothing changed" and "sync is broken" look identical * from outside, and a consumer that cannot tell them apart has to guess. */ readonly SYNC_COMPLETED: "sync_completed"; }; export type HookEventName = (typeof HookEvent)[keyof typeof HookEvent]; /** Every event name, for validating a config file and for telling a user what they may write. */ export declare const HOOK_EVENT_NAMES: readonly HookEventName[]; export declare const VerdictHookPayloadSchema: z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; } & { event: z.ZodLiteral<"verdict">; tool: z.ZodString; verified: z.ZodString; because: z.ZodOptional; sessionId: z.ZodOptional; url: z.ZodOptional; }, "strip", z.ZodTypeAny, { event: "verdict"; at: string; tool: string; verified: string; projectId?: string | undefined; url?: string | undefined; sessionId?: string | undefined; because?: string | undefined; }, { event: "verdict"; at: string; tool: string; verified: string; projectId?: string | undefined; url?: string | undefined; sessionId?: string | undefined; because?: string | undefined; }>; export type VerdictHookPayload = z.infer; export declare const BugFoundHookPayloadSchema: z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; } & { event: z.ZodLiteral<"bug_found">; kind: z.ZodString; source: z.ZodOptional; fingerprint: z.ZodOptional; repeat: z.ZodBoolean; route: z.ZodOptional; tool: z.ZodString; sessionId: z.ZodOptional; }, "strip", z.ZodTypeAny, { event: "bug_found"; kind: string; at: string; tool: string; repeat: boolean; route?: string | undefined; source?: string | undefined; projectId?: string | undefined; sessionId?: string | undefined; fingerprint?: string | undefined; }, { event: "bug_found"; kind: string; at: string; tool: string; repeat: boolean; route?: string | undefined; source?: string | undefined; projectId?: string | undefined; sessionId?: string | undefined; fingerprint?: string | undefined; }>; export type BugFoundHookPayload = z.infer; export declare const SessionHookPayloadSchema: z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; } & { event: z.ZodEnum<["session_started", "session_ended"]>; sessionId: z.ZodString; url: z.ZodOptional; runtime: z.ZodOptional; }, "strip", z.ZodTypeAny, { event: "session_started" | "session_ended"; at: string; sessionId: string; projectId?: string | undefined; url?: string | undefined; runtime?: string | undefined; }, { event: "session_started" | "session_ended"; at: string; sessionId: string; projectId?: string | undefined; url?: string | undefined; runtime?: string | undefined; }>; export type SessionHookPayload = z.infer; export declare const SyncHookPayloadSchema: z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; } & { event: z.ZodLiteral<"sync_completed">; runsPushed: z.ZodNumber; ok: z.ZodBoolean; error: z.ZodOptional; }, "strip", z.ZodTypeAny, { event: "sync_completed"; ok: boolean; at: string; runsPushed: number; error?: string | undefined; projectId?: string | undefined; }, { event: "sync_completed"; ok: boolean; at: string; runsPushed: number; error?: string | undefined; projectId?: string | undefined; }>; export type SyncHookPayload = z.infer; /** Any hook payload. A consumer narrows on `event`, which every variant carries as a literal. */ export declare const HookPayloadSchema: z.ZodDiscriminatedUnion<"event", [z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; } & { event: z.ZodLiteral<"verdict">; tool: z.ZodString; verified: z.ZodString; because: z.ZodOptional; sessionId: z.ZodOptional; url: z.ZodOptional; }, "strip", z.ZodTypeAny, { event: "verdict"; at: string; tool: string; verified: string; projectId?: string | undefined; url?: string | undefined; sessionId?: string | undefined; because?: string | undefined; }, { event: "verdict"; at: string; tool: string; verified: string; projectId?: string | undefined; url?: string | undefined; sessionId?: string | undefined; because?: string | undefined; }>, z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; } & { event: z.ZodLiteral<"bug_found">; kind: z.ZodString; source: z.ZodOptional; fingerprint: z.ZodOptional; repeat: z.ZodBoolean; route: z.ZodOptional; tool: z.ZodString; sessionId: z.ZodOptional; }, "strip", z.ZodTypeAny, { event: "bug_found"; kind: string; at: string; tool: string; repeat: boolean; route?: string | undefined; source?: string | undefined; projectId?: string | undefined; sessionId?: string | undefined; fingerprint?: string | undefined; }, { event: "bug_found"; kind: string; at: string; tool: string; repeat: boolean; route?: string | undefined; source?: string | undefined; projectId?: string | undefined; sessionId?: string | undefined; fingerprint?: string | undefined; }>, z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; sessionId: z.ZodString; url: z.ZodOptional; runtime: z.ZodOptional; } & { event: z.ZodLiteral<"session_started">; }, "strip", z.ZodTypeAny, { event: "session_started"; at: string; sessionId: string; projectId?: string | undefined; url?: string | undefined; runtime?: string | undefined; }, { event: "session_started"; at: string; sessionId: string; projectId?: string | undefined; url?: string | undefined; runtime?: string | undefined; }>, z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; sessionId: z.ZodString; url: z.ZodOptional; runtime: z.ZodOptional; } & { event: z.ZodLiteral<"session_ended">; }, "strip", z.ZodTypeAny, { event: "session_ended"; at: string; sessionId: string; projectId?: string | undefined; url?: string | undefined; runtime?: string | undefined; }, { event: "session_ended"; at: string; sessionId: string; projectId?: string | undefined; url?: string | undefined; runtime?: string | undefined; }>, z.ZodObject<{ at: z.ZodString; projectId: z.ZodOptional; } & { event: z.ZodLiteral<"sync_completed">; runsPushed: z.ZodNumber; ok: z.ZodBoolean; error: z.ZodOptional; }, "strip", z.ZodTypeAny, { event: "sync_completed"; ok: boolean; at: string; runsPushed: number; error?: string | undefined; projectId?: string | undefined; }, { event: "sync_completed"; ok: boolean; at: string; runsPushed: number; error?: string | undefined; projectId?: string | undefined; }>]>; export type HookPayload = z.infer; /** * The file a user writes: event name to command. * * A single command per event, deliberately. A list would invite "run these five things in order", * which is a build system, and the shell already has one — a user who needs two things writes a * script that does two things, and keeps the failure handling where they can see it. */ export declare const HookConfigSchema: z.ZodRecord; export type HookConfig = z.infer;