feat(hooks): add Claude Code hooks type definitions
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
35
notepad.md
35
notepad.md
@@ -431,3 +431,38 @@ All tasks execution STARTED: Thu Dec 4 16:52:57 KST 2025
|
||||
|
||||
---
|
||||
|
||||
## [2025-12-09 17:34] - Task 1: types.ts 포팅
|
||||
|
||||
### DISCOVERED ISSUES
|
||||
- Stub types.ts had `PluginConfig` interface needed by hook-disabled.ts (from Task 0)
|
||||
- Full types.ts from opencode-cc-plugin did NOT have `PluginConfig`
|
||||
- Typecheck initially failed: Module has no exported member 'PluginConfig'
|
||||
|
||||
### IMPLEMENTATION DECISIONS
|
||||
- Copied full types.ts (181 lines) from opencode-cc-plugin → oh-my-opencode
|
||||
- Preserved ALL types: ClaudeHooksConfig, HookMatcher, PreToolUseInput/Output, PostToolUseInput/Output
|
||||
- Preserved deprecated decision fields: `decision?: "allow" | "deny" | "approve" | "block" | "ask"`
|
||||
- Added `PluginConfig` interface at end (oh-my-opencode specific type needed by hook-disabled.ts)
|
||||
- Kept line 150 comment (`// "pending" | "in_progress" | "completed"`) - existing source comment
|
||||
|
||||
### PROBLEMS FOR NEXT TASKS
|
||||
- PluginConfig is now available for all subsequent tasks
|
||||
- Full type definitions ready for Task 2, 3, 4+ to use
|
||||
|
||||
### VERIFICATION RESULTS
|
||||
- Ran: `bun run typecheck` → exit 0, no errors
|
||||
- Verified: ClaudeHooksConfig, HookMatcher, HookCommand types exist
|
||||
- Verified: PreToolUseInput/Output, PostToolUseInput/Output types exist
|
||||
- Verified: deprecated decision field (approve/block) included in PreToolUseOutput
|
||||
- Verified: PluginConfig export added (fixes hook-disabled.ts import)
|
||||
|
||||
### LEARNINGS
|
||||
- opencode-cc-plugin types.ts: 181 lines, no PluginConfig
|
||||
- oh-my-opencode requires PluginConfig for hook disabling functionality
|
||||
- Stub-to-full replacement pattern works: stub allows Task 0 typecheck, Task 1 replaces with full implementation
|
||||
- Must preserve project-specific types (PluginConfig) when porting from different codebases
|
||||
|
||||
소요 시간: ~2분
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
// Temporary stub types for Task 0 - will be fully implemented in Task 1
|
||||
// These are minimal definitions to allow shared utilities to type-check
|
||||
/**
|
||||
* Claude Code Hooks Type Definitions
|
||||
* Maps Claude Code hook concepts to OpenCode plugin events
|
||||
*/
|
||||
|
||||
export interface HookCommand {
|
||||
type: string
|
||||
command: string
|
||||
}
|
||||
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[]
|
||||
@@ -18,7 +26,158 @@ export interface ClaudeHooksConfig {
|
||||
Stop?: HookMatcher[]
|
||||
}
|
||||
|
||||
export type ClaudeHookEvent = "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop"
|
||||
export interface PreToolUseInput {
|
||||
session_id: string
|
||||
transcript_path?: string
|
||||
cwd: string
|
||||
permission_mode?: PermissionMode
|
||||
hook_event_name: "PreToolUse"
|
||||
tool_name: string
|
||||
tool_input: Record<string, unknown>
|
||||
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<string, unknown>
|
||||
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<string, unknown>
|
||||
}
|
||||
}
|
||||
|
||||
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<string, unknown>
|
||||
tool_output?: Record<string, unknown>
|
||||
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 // "pending" | "in_progress" | "completed"
|
||||
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<string, unknown> }
|
||||
| { 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[]
|
||||
|
||||
Reference in New Issue
Block a user