import type { HandoffDescription } from '@mnemonik/shared/git-edit-detector'; import type { HookCredential } from '@mnemonik/credentials'; /** * Tiny HTTP client for the hook → Mnemonik server path. Hard 2-second budget; * any timeout / network error returns null so the dispatcher fails open. * * Uses Node 20's global `fetch` — zero npm dependencies on the runtime side. */ import type { AmbientResponse, FileContextResponse, McpPrecheckResponse, InjectionsResponse, JitResponse, PreCompactResponse, DeliveryConfirmation } from './types.js'; /** * Auto-fetch file_context for an uncovered Edit target. Server returns a * pre-formatted summary string ready for `additionalContext` injection. * Soft-fails (returns null) on auth / lookup / timeout — dispatcher proceeds * with the plain nudge in that case. */ export interface FetchFileContextInput { server: string; apiKey: HookCredential; cwd: string; projectId?: string; projectRoot?: string; claudeSessionId: string; filePath: string; } export declare function fetchFileContext(input: FetchFileContextInput): Promise; /** * Server-driven injection lookup — POST /api/v1/hooks/injections. * * The bus has already applied dedup + work-state hold + per-signal kill * switches, so we just post the current hook event + minimal context and * render whatever envelopes come back. Fail-open on timeout / network / * 4xx (null return) — the agent never breaks because the bus had a hiccup. * * Plan: docs/development/injection-bus.plan.md §7.3 (completion plan PR G). */ export interface FetchInjectionsInput { server: string; apiKey: HookCredential; cwd: string; projectId?: string; projectRoot?: string; sessionId: string; /** Subagent id (`agent_id`) when the event fired inside a subagent. */ agentId?: string; event: 'PreToolUse' | 'PostToolUse' | 'UserPromptSubmit' | 'SessionStart' | 'SubagentStart' | 'Stop'; source?: string; host?: 'claude_code' | 'codex' | 'cursor' | 'vscode'; prompt?: string; ambientDelivered?: boolean; toolName?: string; toolArgs?: Record; toolResultExcerpt?: string; toolUseId?: string; confirmations?: DeliveryConfirmation[]; jitDeliveryAcks?: string[]; hookVersion?: string; actionObservation?: import('./types.js').ActionObservationPayload; stopHookActive?: boolean; /** Edit-style PreToolUse: absolute paths the host is about to write to. */ filePaths?: string[]; /** * Shell PreToolUse: what each handoff in the command carries (repository * and, for a git push, the files its new commits change), for the server's * handoff checkpoint gate. */ handoff?: HandoffDescription[]; /** IANA timezone captured from the host machine (Intl.DateTimeFormat resolution). */ tz?: string; } export declare function fetchInjections(input: FetchInjectionsInput): Promise; /** * JIT Knowledge Injector — Ph3 hook-side caller. Posts the user prompt * to /api/v1/hooks/jit and returns the gate result (envelope + memoryIds * + verdicts) or null on timeout / network / 4xx. Soft-fails so the * dispatcher never blocks the agent's turn on JIT-side errors. The hook * package's source field rides into auth_events.jit_delivered metadata * for Ph6 host-compliance pivoting. */ export interface FetchJitInput { server: string; apiKey: HookCredential; cwd?: string; projectId?: string; projectRoot?: string; sessionId: string; /** Subagent the prompt fired in; absent on the main thread. */ agentId?: string; prompt: string; recentMemoryIds?: string[]; source: 'proxy' | 'cursor_hook' | 'claude_code_hook' | 'codex_hook' | 'vscode_hook'; } export declare function fetchJit(input: FetchJitInput): Promise; /** * Ambient recall — Ph4 hook-side caller. Posts the user prompt to * /api/v1/hooks/ambient-recall and returns the gate result, or null on * timeout / network / non-200. Soft-fails by contract: ambient is advisory * and must never block the agent's turn (ambient-recall.plan.md §2.6). * * The endpoint has existed since May 2026; until now no hook package called * it, so Config-B sessions received no ambient recall at all. */ export interface FetchAmbientInput { server: string; apiKey: HookCredential; cwd?: string; projectId?: string; projectRoot?: string; sessionId: string; /** Subagent the prompt fired in; absent on the main thread. */ agentId?: string; prompt: string; } export declare function fetchAmbient(input: FetchAmbientInput): Promise; export interface PostAfterthoughtInput { server: string; apiKey: HookCredential; cwd: string; projectId?: string; projectRoot?: string; sessionId: string; agentId?: string; assistantText: string; } /** * End-of-turn observation: hand the agent's finished answer to the server and * return. The server recalls on it in the background and queues anything that * stands out for the next hook event's drain, so nothing is read back here. * Telemetry budget, awaited by the caller because the hook exits right after * and an exit cancels an unfinished write. */ export declare function postAfterthought(input: PostAfterthoughtInput): Promise; /** * MCP precheck — server-side ordering-rule engine verdict for an about-to-run * Mnemonik MCP call. Used by handlePreMcp for the `mcp__mnemonik__.*` matcher * (cursor-hooks.plan.md §16). Soft-fails (null) on timeout / network / 4xx so * the dispatcher fails open and the agent's call proceeds. */ export interface FetchMcpPrecheckInput { server: string; apiKey: HookCredential; cwd: string; projectId?: string; projectRoot?: string; claudeSessionId: string; agentId?: string; tool: string; args: Record; model?: string; actionObservation?: import('./types.js').ActionObservationPayload; } export declare function fetchMcpPrecheck(input: FetchMcpPrecheckInput): Promise; export interface FetchMcpRecordInput { server: string; apiKey: HookCredential; cwd: string; projectId?: string; projectRoot?: string; claudeSessionId: string; agentId?: string; tool: string; args: Record; result: unknown; actionObservation?: import('./types.js').ActionObservationPayload; } export declare function fetchMcpRecord(input: FetchMcpRecordInput): Promise; /** * Fire-and-forget gate-firing telemetry. Every PreToolUse decision (allow, * deny, advisory nudge, dedup, soft-pass, bypass, etc.) emits one of these * so the dashboard can split firing rate by tool / mode / outcome and * detect regressions like "advisory nudge rate spiked after a server * deploy". Loss is acceptable — the value is in volume, not per-event. */ export interface ReportGateFiredInput { server: string; apiKey: HookCredential | null; cwd: string; projectId?: string; projectRoot?: string; claudeSessionId: string; tool: string; mode: 'advisory' | 'enforce' | 'off'; outcome: string; actionObservation?: import('./types.js').ActionObservationPayload; } export declare function reportGateFired(input: ReportGateFiredInput): Promise; /** * Fire-and-forget bypass telemetry. We always write to a local audit log and * additionally try to POST it to the server, but neither failure is allowed * to delay or block the hook decision. */ export interface ReportBypassInput { server: string; apiKey: HookCredential | null; cwd: string; projectId?: string; projectRoot?: string; claudeSessionId: string; tool: string; bypassType: string; detail: string | null; } export declare function reportBypass(input: ReportBypassInput): Promise; /** * v1.1: native-Grep observed ping. Claude Code's built-in Grep tool is a * text search by definition, so every PreToolUse with toolName 'Grep' * should count toward the code_search_reminder nudge server-side * (HooksDispatcher's PreToolUse handler, the `tool === 'Grep'` branch) — * mirroring the shell-command grep/rg/ag counter. POSTs to the same * injections endpoint fetchInjections() calls, primarily for its counting * side effect. Reading the response body of the POST we already send adds no * new round-trip — the AbortController signal aborts the body read too, so the * `await res.json()` stays inside the same 500 ms timer — so we also return the * parsed injections. When the increment crosses the grep threshold the server * pushes a code_search_reminder nudge in THAT response, and handlePreGrep * surfaces it as advisory additionalContext. * * Grep is a high-frequency tool call, so this reuses the reportGateFired / * reportBypass shape — a hard 500 ms budget (TELEMETRY_TIMEOUT_MS), not the * 2 s fetchInjections budget (FETCH_TIMEOUT_MS) reserved for hooks that * actually consume the response to build a decision. Loss is acceptable — * the value is in volume, not per-event — the same tradeoff already * accepted for gate-fired telemetry, which fires on every single * Edit/Write/Bash PreToolUse call today via this identical bounded shape. * Returns null on timeout / network error / non-2xx so the caller fails open. */ export interface ReportNativeGrepInput { server: string; apiKey: HookCredential | null; cwd: string; projectId?: string; projectRoot?: string; sessionId: string; agentId?: string; toolName?: string; actionObservation?: import('./types.js').ActionObservationPayload; } export declare function reportNativeGrepObserved(input: ReportNativeGrepInput): Promise; interface BaseHookInput { server: string; apiKey: HookCredential; cwd: string; projectId?: string; projectRoot?: string; claudeSessionId: string; /** IANA timezone captured from the host machine. */ tz?: string; actionObservation?: import('./types.js').ActionObservationPayload; } /** Worst case of postProxySuppressionClear: every attempt times out after its wait. */ export declare const PROXY_SUPPRESSION_CLEAR_WORST_MS: number; /** SessionStart coord — tells the proxy bootstrap was hook-preloaded. */ export declare function postSessionStart(input: BaseHookInput): Promise; /** * SessionEnd hook clears server state and stores the ended-session marker. * The server can ask for a retry when it cannot store that marker. Two short * retries keep the cleanup bounded while giving a recovering server another * chance to accept it. */ export declare function postProxySuppressionClear(input: BaseHookInput): Promise; export interface CreatePreCompactSnapshotInput extends BaseHookInput { summary?: string; nextSteps?: string[]; filesInProgress?: string[]; } /** * PreCompact snapshot — synchronous because Claude Code holds the compaction * pause until the hook returns, and we want the snapshot ID in the * additionalContext that survives compaction. 4s budget (PRECOMPACT_TIMEOUT_MS) * is specific to this endpoint; it does not gate bootstrap-digest delivery. */ export declare function createPreCompactSnapshot(input: CreatePreCompactSnapshotInput): Promise; export interface PostSessionEndInput extends BaseHookInput { reason?: string; } /** SessionEnd save — fire-and-forget; the session is closing anyway. */ export declare function postSessionEnd(input: PostSessionEndInput): Promise; export interface PostContextStatsInput { server: string; apiKey: HookCredential; cwd: string; projectId?: string; projectRoot?: string; sessionId: string; /** Live context-window input-token count (Claude Code statusline * context_window.total_input_tokens). */ contextTokens: number; } /** * Statusline context-stats report (temporal-grounding Phase 0 config-C * ingestion). Fire-and-forget on the TELEMETRY budget — the statusline has * already printed its line by the time this runs; a failed report only costs * the server one compaction-detection sample. Matches hooksContextStatsSchema * (cwd, projectId?, sessionId, contextTokens, host). */ export declare function postContextStats(input: PostContextStatsInput): Promise; export {};