/** * Plugin hooks — wires OpenCode events to OTEL metrics and log events. * * All hook types (server events, tool execution, chat messages, commands) * are unified through a single `handleEvent` dispatcher. Each hook in * index.ts packages its input into a `{ type, properties }` event and * delegates here. */ import type { OtelConfig } from "./config.js"; import type { TelemetryContext } from "./telemetry.js"; import type { Logger } from "./log.js"; interface SessionState { sessionId: string; startedAt: number; lastActivityAt: number; } interface ToolCallState { tool: string; startedAt: number; args: unknown; } export interface HookState { config: OtelConfig; telemetry: TelemetryContext; log: Logger; sessions: Map; pendingToolCalls: Map; /** Set of message IDs that have already had their api_request event emitted * via message.updated, so we can skip duplicate emission from step-finish parts. */ emittedMessageIds: Set; eventSequence: number; /** Runtime toggle — when false, telemetry emission is skipped. */ enabled: boolean; /** Persistent anonymous user ID (64-char hex, matches Claude Code format). */ userId: string; /** Detected terminal type (e.g. "vscode", "zed", "tmux"). */ terminalType: string | undefined; /** Current prompt ID (randomUUID, set per user prompt). */ promptId: string | undefined; /** OpenCode version, captured from the first session.created event. */ opencodeVersion: string | undefined; /** Current model provider ID (captured from chat.message events). */ currentProvider: string | undefined; /** Provider match state — undefined means still buffering (waiting for first provider), * true means provider matches and we emit telemetry, false means skip telemetry. */ providerMatch: boolean | undefined; /** Buffered provider-specific events (emitted once provider is known). */ pendingEvents: Array<() => void>; } export declare function createHookState(config: OtelConfig, telemetry: TelemetryContext, log: Logger): HookState; /** Name of the slash command this plugin intercepts. */ export declare const OTEL_COMMAND_NAME = "otel"; /** * Result returned by `handleEvent` for events that need the caller to * perform side-effects (e.g. show a toast). */ export interface HandleEventResult { /** Present when the /otel toggle command was handled. */ otelToggled?: { enabled: boolean; }; } /** * Central dispatcher — every hook type is routed here as a * `{ type, properties }` event. * * Synthetic event types used by index.ts: * - "command.execute.before" — slash command interception * - "tool.execute.before" — tool call start * - "tool.execute.after" — tool call end * - "chat.message" — user prompt * * Server-pushed event types (forwarded as-is): * - "session.created", "session.idle", "session.status" * - "file.edited", "message.part.updated", … */ export declare function handleEvent(state: HookState, event: { type: string; properties?: any; }): HandleEventResult | undefined; export {};