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 {
|
export type ClaudeHookEvent =
|
||||||
type: string
|
| "PreToolUse"
|
||||||
command: string
|
| "PostToolUse"
|
||||||
}
|
| "UserPromptSubmit"
|
||||||
|
| "Stop"
|
||||||
|
|
||||||
export interface HookMatcher {
|
export interface HookMatcher {
|
||||||
matcher: string
|
matcher: string
|
||||||
hooks: HookCommand[]
|
hooks: HookCommand[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HookCommand {
|
||||||
|
type: "command"
|
||||||
|
command: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface ClaudeHooksConfig {
|
export interface ClaudeHooksConfig {
|
||||||
PreToolUse?: HookMatcher[]
|
PreToolUse?: HookMatcher[]
|
||||||
PostToolUse?: HookMatcher[]
|
PostToolUse?: HookMatcher[]
|
||||||
@@ -18,7 +26,158 @@ export interface ClaudeHooksConfig {
|
|||||||
Stop?: HookMatcher[]
|
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 {
|
export interface PluginConfig {
|
||||||
disabledHooks?: boolean | ClaudeHookEvent[]
|
disabledHooks?: boolean | ClaudeHookEvent[]
|
||||||
|
|||||||
Reference in New Issue
Block a user