/** * Claude Code Hooks Type Definitions * Maps Claude Code hook concepts to OpenCode plugin events */ export type ClaudeHookEvent = "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop"; export interface HookMatcher { matcher: string; hooks: HookCommand[]; } export interface HookCommand { type: "command"; command: string; } export interface ClaudeHooksConfig { PreToolUse?: HookMatcher[]; PostToolUse?: HookMatcher[]; UserPromptSubmit?: HookMatcher[]; Stop?: HookMatcher[]; } export interface PreToolUseInput { session_id: string; transcript_path?: string; cwd: string; permission_mode?: PermissionMode; hook_event_name: "PreToolUse"; tool_name: string; tool_input: Record; tool_use_id?: string; hook_source?: HookSource; } export interface PostToolUseInput { session_id: string; transcript_path?: string; cwd: string; permission_mode?: PermissionMode; hook_event_name: "PostToolUse"; tool_name: string; tool_input: Record; tool_response: { title?: string; output?: string; [key: string]: unknown; }; tool_use_id?: string; hook_source?: HookSource; } export interface UserPromptSubmitInput { session_id: string; cwd: string; permission_mode?: PermissionMode; hook_event_name: "UserPromptSubmit"; prompt: string; session?: { id: string; }; hook_source?: HookSource; } export type PermissionMode = "default" | "plan" | "acceptEdits" | "bypassPermissions"; export type HookSource = "opencode-plugin"; export interface StopInput { session_id: string; transcript_path?: string; cwd: string; permission_mode?: PermissionMode; hook_event_name: "Stop"; stop_hook_active: boolean; todo_path?: string; hook_source?: HookSource; } export type PermissionDecision = "allow" | "deny" | "ask"; /** * Common JSON fields for all hook outputs (Claude Code spec) */ export interface HookCommonOutput { /** If false, Claude stops entirely */ continue?: boolean; /** Message shown to user when continue=false */ stopReason?: string; /** Suppress output from transcript */ suppressOutput?: boolean; /** Warning/message displayed to user */ systemMessage?: string; } export interface PreToolUseOutput extends HookCommonOutput { /** Deprecated: use hookSpecificOutput.permissionDecision instead */ decision?: "allow" | "deny" | "approve" | "block" | "ask"; /** Deprecated: use hookSpecificOutput.permissionDecisionReason instead */ reason?: string; hookSpecificOutput?: { hookEventName: "PreToolUse"; permissionDecision: PermissionDecision; permissionDecisionReason?: string; updatedInput?: Record; }; } export interface PostToolUseOutput extends HookCommonOutput { decision?: "block"; reason?: string; hookSpecificOutput?: { hookEventName: "PostToolUse"; /** Additional context to provide to Claude */ additionalContext?: string; }; } export interface HookResult { exitCode: number; stdout?: string; stderr?: string; } export interface TranscriptEntry { type: "tool_use" | "tool_result" | "user" | "assistant"; timestamp: string; tool_name?: string; tool_input?: Record; tool_output?: Record; content?: string; } export interface TodoItem { id: string; content: string; status: "pending" | "in_progress" | "completed" | "cancelled"; priority?: "low" | "medium" | "high"; created_at: string; updated_at?: string; } export interface ClaudeCodeTodoItem { content: string; status: string; activeForm: string; } export interface TodoFile { session_id: string; items: TodoItem[]; created_at: string; updated_at: string; } export interface StopOutput { decision?: "block" | "continue"; reason?: string; stop_hook_active?: boolean; permission_mode?: PermissionMode; inject_prompt?: string; } export type ClaudeCodeContent = { type: "text"; text: string; } | { type: "tool_use"; id: string; name: string; input: Record; } | { type: "tool_result"; tool_use_id: string; content: string; }; export interface ClaudeCodeMessage { type: "user" | "assistant"; message: { role: "user" | "assistant"; content: ClaudeCodeContent[]; }; } export interface PluginConfig { disabledHooks?: boolean | ClaudeHookEvent[]; }