oh-my-opencode 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -15,6 +15,7 @@
15
15
  - [내장 AST-Grep Tools](#내장-ast-grep-tools)
16
16
  - [Grep](#grep)
17
17
  - [내장 MCPs](#내장-mcps)
18
+ - [Claude Code 호환성](#claude-code-호환성)
18
19
  - [기타 편의 기능](#기타-편의-기능)
19
20
  - [설정](#설정)
20
21
  - [작성자의 노트](#작성자의-노트)
@@ -105,7 +106,19 @@ opencode --version # 1.0.132 이상이어야 함
105
106
  cat ~/.config/opencode/opencode.json # plugin 배열에 "oh-my-opencode"가 있어야 함
106
107
  ```
107
108
 
108
- > **참고**: 모델 인증이 필요하면, `opencode` 실행 후 `/connect` 명령어를 사용하거나, tmux를 통해 `opencode auth login`을 안내하세요.
109
+ ### 4단계: 인증정보 설정
110
+
111
+ plugin 에 oh my opencode 를 추가했다면, tmux 를 사용하여 다음의 내용을 진행주세요.
112
+
113
+ 1. tmux 를 사용하여 셸 열기
114
+ 2. opencode auth login > Provider Anthropic > Login method Claude Pro/Max > 사용자에게 oauth 화면에서 인증하라고 안내
115
+ 3. 사용자에게 macOS 일 경우 VibeProxy, 아닐 경우 CLIProxyAPI 를 사용하여 OpenAI / Google 인증을 완료하라고 안내
116
+
117
+ ### ⚠️ 주의
118
+
119
+ **사용자가 명시적으로 요청하지 않는 한, `oh-my-opencode.json` 설정 파일을 생성하거나 수정하지 마세요.**
120
+
121
+ 플러그인은 설정 파일 없이도 기본값으로 완벽하게 동작합니다. 설정 파일은 사용자가 커스터마이징을 원할 때만 필요합니다.
109
122
 
110
123
  </details>
111
124
 
@@ -224,17 +237,72 @@ OpenCode 는 아주 확장가능하고 아주 커스터마이저블합니다.
224
237
  }
225
238
  ```
226
239
 
240
+ ### Claude Code 호환성
241
+
242
+ Oh My OpenCode는 Claude Code 설정과 완벽하게 호환됩니다. Claude Code를 사용하셨다면, 기존 설정을 그대로 사용할 수 있습니다.
243
+
244
+ #### Hooks 통합
245
+
246
+ Claude Code의 `settings.json` 훅 시스템을 통해 커스텀 스크립트를 실행합니다. Oh My OpenCode는 다음 위치의 훅을 읽고 실행합니다:
247
+
248
+ - `~/.claude/settings.json` (사용자)
249
+ - `./.claude/settings.json` (프로젝트)
250
+ - `./.claude/settings.local.json` (로컬, git-ignored)
251
+
252
+ 지원되는 훅 이벤트:
253
+ - **PreToolUse**: 도구 실행 전에 실행. 차단하거나 도구 입력을 수정할 수 있습니다.
254
+ - **PostToolUse**: 도구 실행 후에 실행. 경고나 컨텍스트를 추가할 수 있습니다.
255
+ - **UserPromptSubmit**: 사용자가 프롬프트를 제출할 때 실행. 차단하거나 메시지를 주입할 수 있습니다.
256
+ - **Stop**: 세션이 유휴 상태가 될 때 실행. 후속 프롬프트를 주입할 수 있습니다.
257
+
258
+ `settings.json` 예시:
259
+ ```json
260
+ {
261
+ "hooks": {
262
+ "PostToolUse": [
263
+ {
264
+ "matcher": "Write|Edit",
265
+ "hooks": [{ "type": "command", "command": "eslint --fix $FILE" }]
266
+ }
267
+ ]
268
+ }
269
+ }
270
+ ```
271
+
272
+ #### 설정 로더
273
+
274
+ **Command Loader**: 4개 디렉토리에서 마크다운 기반 슬래시 명령어를 로드합니다:
275
+ - `~/.claude/commands/` (사용자)
276
+ - `./.claude/commands/` (프로젝트)
277
+ - `~/.config/opencode/command/` (opencode 전역)
278
+ - `./.opencode/command/` (opencode 프로젝트)
279
+
280
+ **Skill Loader**: `SKILL.md`가 있는 디렉토리 기반 스킬을 로드합니다:
281
+ - `~/.claude/skills/` (사용자)
282
+ - `./.claude/skills/` (프로젝트)
283
+
284
+ **Agent Loader**: 마크다운 파일에서 커스텀 에이전트 정의를 로드합니다:
285
+ - `~/.claude/agents/*.md` (사용자)
286
+ - `./.claude/agents/*.md` (프로젝트)
287
+
288
+ **MCP Loader**: `.mcp.json` 파일에서 MCP 서버 설정을 로드합니다:
289
+ - `~/.claude/.mcp.json` (사용자)
290
+ - `./.mcp.json` (프로젝트)
291
+ - `./.claude/.mcp.json` (로컬)
292
+ - 환경변수 확장 지원 (`${VAR}` 문법)
293
+
294
+ #### 데이터 저장소
295
+
296
+ **Todo 관리**: 세션 todo가 `~/.claude/todos/`에 Claude Code 호환 형식으로 저장됩니다.
297
+
298
+ **Transcript**: 세션 활동이 `~/.claude/transcripts/`에 JSONL 형식으로 기록되어 재생 및 분석이 가능합니다.
299
+
300
+ > **`claude-code-*` 네이밍에 대해**: `src/features/claude-code-*/` 아래의 기능들은 Claude Code의 설정 시스템에서 마이그레이션되었습니다. 이 네이밍 규칙은 어떤 기능이 Claude Code에서 유래했는지 명확히 식별합니다.
301
+
227
302
  ### 기타 편의 기능
228
303
 
229
304
  - **Terminal Title**: 세션 상태에 따라 터미널 타이틀을 자동 업데이트합니다 (유휴 ○, 처리중 ◐, 도구 ⚡, 에러 ✖). tmux를 지원합니다.
230
- - **Command Loader**: 다음 디렉토리들에서 마크다운 기반의 커스텀 명령어들을 로드합니다:
231
- - User scope: `~/.claude/commands/`
232
- - Project scope: `./.claude/commands/`
233
- - OpenCode global: `~/.config/opencode/command/`
234
- - OpenCode project: `./.opencode/command/`
235
- - **Skill Loader**: 다음 디렉토리들에서 디렉토리 기반의 스킬들을 실행 가능한 명령어로 로드합니다:
236
- - User scope: `~/.claude/skills/`
237
- - Project scope: `./.claude/skills/`
305
+ - **Session State**: 이벤트 훅과 터미널 타이틀 업데이트에 사용되는 중앙집중식 세션 추적 모듈입니다.
238
306
 
239
307
  ## 설정
240
308
 
@@ -270,7 +338,7 @@ Schema 자동 완성이 지원됩니다:
270
338
 
271
339
  각 에이전트에서 지원하는 옵션: `model`, `temperature`, `top_p`, `prompt`, `tools`, `disable`, `description`, `mode`, `color`, `permission`.
272
340
 
273
- 또는 `disabled_agents`로 비활성화할 수 있습니다:
341
+ 또는 ~/.config/opencode/oh-my-opencode.json 혹은 .opencode/oh-my-opencode.json 의 `disabled_agents` 를 사용하여 비활성화할 수 있습니다:
274
342
 
275
343
  ```json
276
344
  {
@@ -282,7 +350,9 @@ Schema 자동 완성이 지원됩니다:
282
350
 
283
351
  ### MCPs
284
352
 
285
- 내장된 MCP를 비활성화합니다:
353
+ 기본적으로 Context7, Exa MCP 지원합니다.
354
+
355
+ 이것이 마음에 들지 않는다면, ~/.config/opencode/oh-my-opencode.json 혹은 .opencode/oh-my-opencode.json 의 `disabled_mcps` 를 사용하여 비활성화할 수 있습니다:
286
356
 
287
357
  ```json
288
358
  {
@@ -290,13 +360,13 @@ Schema 자동 완성이 지원됩니다:
290
360
  }
291
361
  ```
292
362
 
293
- 더 자세한 내용은 [OpenCode MCP Servers](https://opencode.ai/docs/mcp-servers)를 참조하세요.
294
-
295
363
  ### LSP
296
364
 
297
- Oh My OpenCode LSP 도구는 오직 **리팩토링(이름 변경, 코드 액션)만을 위한 것**입니다. 분석용 LSP OpenCode 자체에서 처리합니다.
365
+ OpenCode 분석을 위해 LSP 도구를 제공합니다.
366
+ Oh My OpenCode 에서는 LSP 의 리팩토링(이름 변경, 코드 액션) 도구를 제공합니다.
367
+ OpenCode 에서 지원하는 모든 LSP 구성 및 커스텀 설정 (opencode.json 에 설정 된 것) 을 그대로 지원하고, Oh My OpenCode 만을 위한 추가적인 설정도 아래와 같이 설정 할 수 있습니다.
298
368
 
299
- `lsp` 옵션을 통해 LSP 서버를 설정합니다:
369
+ ~/.config/opencode/oh-my-opencode.json 혹은 .opencode/oh-my-opencode.json 의 `lsp` 옵션을 통해 LSP 서버를 추가로 설정 할 수 있습니다:
300
370
 
301
371
  ```json
302
372
  {
package/README.md CHANGED
@@ -15,6 +15,7 @@ English | [한국어](README.ko.md)
15
15
  - [Built-in AST-Grep Tools](#built-in-ast-grep-tools)
16
16
  - [Grep](#grep)
17
17
  - [Built-in MCPs](#built-in-mcps)
18
+ - [Claude Code Compatibility](#claude-code-compatibility)
18
19
  - [Other Features](#other-features)
19
20
  - [Configuration](#configuration)
20
21
  - [Author's Note](#authors-note)
@@ -27,11 +28,12 @@ Oh My OpenCode
27
28
  oMoMoMoMoMo···
28
29
 
29
30
  If you work in tech, you likely appreciated [Claude Code](https://www.claude.com/product/claude-code).
30
- If you are a hacker, you will fucking falling in love with [OpenCode](https://github.com/sst/opencode).
31
+ If you are a hacker, you will fucking fall in love with [OpenCode](https://github.com/sst/opencode).
31
32
 
32
- You don't write code just for a paycheck? You write because you genuinely love it?
33
-
34
- To you, OpenCode will feel like the paradigm shift from Windows to Linux. Not you? It's still worth the investment. Give it 10 minutes. Your work and life will improve. I promise.
33
+ Do you remember the first time you switched from Windows to Linux? The excitement of configuring everything just the way you wanted?
34
+ In an era where that romance feels lost, OpenCode will be that project for you.
35
+ If you love coding and computers, OpenCode will feel exactly like that moment you first touched Linux after years of Windows.
36
+ Even if you don't, invest a little time. Boost your skills and productivity by multipliers.
35
37
 
36
38
  ## TL;DR
37
39
 
@@ -41,7 +43,7 @@ To you, OpenCode will feel like the paradigm shift from Windows to Linux. Not yo
41
43
  - For OpenAI models, I recommend the [OpenCode-OpenAI-Codex-Auth plugin](https://github.com/numman-ali/opencode-openai-codex-auth).
42
44
  - For Gemini and GPT, use [VibeProxy (macOS Only)](https://github.com/automazeio/vibeproxy) or [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI).
43
45
  - **Truth be told, the rest is optional. Just install it. Once set up, no further learning is required. It simply evolves.**
44
- - **Paste this document into Claude Code, OpenCode, or Cursor, instruct it to install, and ask for assistance if needed. It works seamlessly.**
46
+ - **Paste this document into Claude Code, OpenCode, or Cursor, instruct it to install, and ask for assistance if needed. It just installs.**
45
47
  - If you are an LLM Agent, install the required plugins and dependencies, then run `opencode auth login` via tmux to assist the user with configuration.
46
48
 
47
49
  ## Installation
@@ -103,7 +105,19 @@ opencode --version # Should be >= 1.0.132
103
105
  cat ~/.config/opencode/opencode.json # Should contain "oh-my-opencode" in plugin array
104
106
  ```
105
107
 
106
- > **Note**: If model authentication is needed, run `opencode` and use `/connect` command, or assist the user with `opencode auth login` via tmux.
108
+ ### Step 4: Configure Authentication
109
+
110
+ Once `oh-my-opencode` is added to the plugin list, use `tmux` to proceed with the following:
111
+
112
+ 1. Open a shell using `tmux`.
113
+ 2. Run `opencode auth login` > Select Provider `Anthropic` > Select Login method `Claude Pro/Max` > Instruct the user to authenticate via the OAuth screen.
114
+ 3. Recommend the setup: [VibeProxy](https://github.com/automazeio/vibeproxy) for macOS users, or [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) for others.
115
+
116
+ ### ⚠️ Warning
117
+
118
+ **Do NOT create or modify the `oh-my-opencode.json` configuration file unless the user explicitly requests it.**
119
+
120
+ The plugin works perfectly with default settings without any configuration file. The configuration file is only needed when the user wants customization.
107
121
 
108
122
  </details>
109
123
 
@@ -114,7 +128,7 @@ OpenCode is limitlessly extensible and customizable. Zero screen flicker.
114
128
  You can mix and orchestrate models to your exact specifications.
115
129
  It is feature-rich. It is elegant. It handles the terminal without hesitation. It is high-performance.
116
130
 
117
- But here is the catch: the learning curve is steep. There is a lot to master.
131
+ But here is the catch: the learning curve is steep. There is a lot to master. And your time is expensive.
118
132
 
119
133
  Inspired by [AmpCode](https://ampcode.com) and [Claude Code](https://code.claude.com/docs/en/overview), I have implemented their features here—often with superior execution.
120
134
  Because this is OpenCode.
@@ -221,29 +235,72 @@ Don't need these? Disable them via `oh-my-opencode.json`:
221
235
  }
222
236
  ```
223
237
 
238
+ ### Claude Code Compatibility
239
+
240
+ Oh My OpenCode provides seamless Claude Code configuration compatibility. If you've been using Claude Code, your existing setup works out of the box.
241
+
242
+ #### Hooks Integration
243
+
244
+ Execute custom scripts via Claude Code's `settings.json` hook system. Oh My OpenCode reads and executes hooks defined in:
245
+
246
+ - `~/.claude/settings.json` (user)
247
+ - `./.claude/settings.json` (project)
248
+ - `./.claude/settings.local.json` (local, git-ignored)
249
+
250
+ Supported hook events:
251
+ - **PreToolUse**: Runs before tool execution. Can block or modify tool input.
252
+ - **PostToolUse**: Runs after tool execution. Can add warnings or context.
253
+ - **UserPromptSubmit**: Runs when user submits a prompt. Can block or inject messages.
254
+ - **Stop**: Runs when session goes idle. Can inject follow-up prompts.
255
+
256
+ Example `settings.json`:
257
+ ```json
258
+ {
259
+ "hooks": {
260
+ "PostToolUse": [
261
+ {
262
+ "matcher": "Write|Edit",
263
+ "hooks": [{ "type": "command", "command": "eslint --fix $FILE" }]
264
+ }
265
+ ]
266
+ }
267
+ }
268
+ ```
269
+
270
+ #### Configuration Loaders
271
+
272
+ **Command Loader**: Loads markdown-based slash commands from 4 directories:
273
+ - `~/.claude/commands/` (user)
274
+ - `./.claude/commands/` (project)
275
+ - `~/.config/opencode/command/` (opencode global)
276
+ - `./.opencode/command/` (opencode project)
277
+
278
+ **Skill Loader**: Loads directory-based skills with `SKILL.md`:
279
+ - `~/.claude/skills/` (user)
280
+ - `./.claude/skills/` (project)
281
+
282
+ **Agent Loader**: Loads custom agent definitions from markdown files:
283
+ - `~/.claude/agents/*.md` (user)
284
+ - `./.claude/agents/*.md` (project)
285
+
286
+ **MCP Loader**: Loads MCP server configurations from `.mcp.json` files:
287
+ - `~/.claude/.mcp.json` (user)
288
+ - `./.mcp.json` (project)
289
+ - `./.claude/.mcp.json` (local)
290
+ - Supports environment variable expansion (`${VAR}` syntax)
291
+
292
+ #### Data Storage
293
+
294
+ **Todo Management**: Session todos are stored in Claude Code compatible format at `~/.claude/todos/`.
295
+
296
+ **Transcript**: Session activity is logged to `~/.claude/transcripts/` in JSONL format, enabling replay and analysis.
297
+
298
+ > **Note on `claude-code-*` naming**: Features under `src/features/claude-code-*/` are migrated from Claude Code's configuration system. This naming convention clearly identifies which features originated from Claude Code.
299
+
224
300
  ### Other Features
225
301
 
226
302
  - **Terminal Title**: Auto-updates terminal title with session status (idle ○, processing ◐, tool ⚡, error ✖). Supports tmux.
227
- - **Command Loader** (`src/features/claude-code-command-loader/`): Loads markdown-based commands from multiple directories:
228
- - User scope: `~/.claude/commands/`
229
- - Project scope: `./.claude/commands/`
230
- - OpenCode global: `~/.config/opencode/command/`
231
- - OpenCode project: `./.opencode/command/`
232
- - **Skill Loader** (`src/features/claude-code-skill-loader/`): Loads directory-based skills as executable commands:
233
- - User scope: `~/.claude/skills/`
234
- - Project scope: `./.claude/skills/`
235
- - **Agent Loader** (`src/features/claude-code-agent-loader/`): Loads agent definitions from markdown files with YAML frontmatter:
236
- - User scope: `~/.claude/agents/`
237
- - Project scope: `./.claude/agents/`
238
- - Format: `*.md` files with frontmatter (name, description, tools)
239
- - **Session State** (`src/features/claude-code-session-state/`): Centralized session tracking module used by event hooks and terminal title updates.
240
- - **MCP Loader** (`src/features/claude-code-mcp-loader/`): Loads MCP server configurations from `.mcp.json` files:
241
- - User scope: `~/.claude/.mcp.json`
242
- - Project scope: `./.mcp.json`
243
- - Local scope: `./.claude/.mcp.json`
244
- - Supports environment variable expansion (`${VAR}` syntax)
245
-
246
- > **Note on `claude-code-*` naming**: Features under `src/features/claude-code-*/` are migrated from Claude Code's configuration system. This naming convention clearly identifies which features originated from Claude Code, such as `claude-code-command-loader`, `claude-code-skill-loader`, `claude-code-agent-loader`, and `claude-code-mcp-loader`.
303
+ - **Session State**: Centralized session tracking module used by event hooks and terminal title updates.
247
304
 
248
305
  ## Configuration
249
306
 
@@ -279,7 +336,7 @@ Override built-in agent settings:
279
336
 
280
337
  Each agent supports: `model`, `temperature`, `top_p`, `prompt`, `tools`, `disable`, `description`, `mode`, `color`, `permission`.
281
338
 
282
- Or disable agents via `disabled_agents`:
339
+ Or you can disable them using `disabled_agents` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`:
283
340
 
284
341
  ```json
285
342
  {
@@ -291,7 +348,9 @@ Available agents: `oracle`, `librarian`, `explore`, `frontend-ui-ux-engineer`, `
291
348
 
292
349
  ### MCPs
293
350
 
294
- Disable built-in MCPs:
351
+ By default, Context7 and Exa MCP are supported.
352
+
353
+ If you don't want these, you can disable them using `disabled_mcps` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`:
295
354
 
296
355
  ```json
297
356
  {
@@ -299,13 +358,13 @@ Disable built-in MCPs:
299
358
  }
300
359
  ```
301
360
 
302
- See [OpenCode MCP Servers](https://opencode.ai/docs/mcp-servers) for more.
303
-
304
361
  ### LSP
305
362
 
306
- Oh My OpenCode's LSP tools are for **refactoring only** (rename, code actions). Analysis LSP is handled by OpenCode itself.
363
+ OpenCode provides LSP tools for analysis.
364
+ Oh My OpenCode provides LSP tools for refactoring (rename, code actions).
365
+ It supports all LSP configurations and custom settings supported by OpenCode (those configured in opencode.json), and you can also configure additional settings specifically for Oh My OpenCode as shown below.
307
366
 
308
- Configure LSP servers via `lsp` option:
367
+ You can configure additional LSP servers via the `lsp` option in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`:
309
368
 
310
369
  ```json
311
370
  {
@@ -345,7 +404,7 @@ If this sounds arrogant and you have a superior solution, send a PR. You are wel
345
404
 
346
405
  As of now, I have no affiliation with any of the projects or models mentioned here. This plugin is purely based on personal experimentation and preference.
347
406
 
348
- I constructed 99% of this project using OpenCode. I focused on functional verification. This documentation has been personally reviewed and comprehensively rewritten, so you can rely on it with confidence.
407
+ I constructed 99% of this project using OpenCode. I focused on functional verification, and honestly, I don't know how to write proper TypeScript. **But I personally reviewed and comprehensively rewritten this documentation, so you can rely on it with confidence.**
349
408
  ## Warnings
350
409
 
351
410
  - If you are on [1.0.132](https://github.com/sst/opencode/releases/tag/v1.0.132) or lower, OpenCode has a bug that might break config.
@@ -0,0 +1,3 @@
1
+ export declare const OPENCODE_STORAGE: string;
2
+ export declare const MESSAGE_STORAGE: string;
3
+ export declare const PART_STORAGE: string;
@@ -0,0 +1,2 @@
1
+ export { injectHookMessage } from "./injector";
2
+ export type { MessageMeta, OriginalMessageContext, TextPart } from "./types";
@@ -0,0 +1,2 @@
1
+ import type { OriginalMessageContext } from "./types";
2
+ export declare function injectHookMessage(sessionID: string, hookContent: string, originalMessage: OriginalMessageContext): boolean;
@@ -0,0 +1,43 @@
1
+ export interface MessageMeta {
2
+ id: string;
3
+ sessionID: string;
4
+ role: "user" | "assistant";
5
+ time: {
6
+ created: number;
7
+ completed?: number;
8
+ };
9
+ agent?: string;
10
+ model?: {
11
+ providerID: string;
12
+ modelID: string;
13
+ };
14
+ path?: {
15
+ cwd: string;
16
+ root: string;
17
+ };
18
+ tools?: Record<string, boolean>;
19
+ }
20
+ export interface OriginalMessageContext {
21
+ agent?: string;
22
+ model?: {
23
+ providerID?: string;
24
+ modelID?: string;
25
+ };
26
+ path?: {
27
+ cwd?: string;
28
+ root?: string;
29
+ };
30
+ tools?: Record<string, boolean>;
31
+ }
32
+ export interface TextPart {
33
+ id: string;
34
+ type: "text";
35
+ text: string;
36
+ synthetic: boolean;
37
+ time: {
38
+ start: number;
39
+ end: number;
40
+ };
41
+ messageID: string;
42
+ sessionID: string;
43
+ }
@@ -0,0 +1,12 @@
1
+ import type { ClaudeHookEvent } from "./types";
2
+ export interface DisabledHooksConfig {
3
+ Stop?: string[];
4
+ PreToolUse?: string[];
5
+ PostToolUse?: string[];
6
+ UserPromptSubmit?: string[];
7
+ }
8
+ export interface PluginExtendedConfig {
9
+ disabledHooks?: DisabledHooksConfig;
10
+ }
11
+ export declare function loadPluginExtendedConfig(): Promise<PluginExtendedConfig>;
12
+ export declare function isHookCommandDisabled(eventType: ClaudeHookEvent, command: string, config: PluginExtendedConfig | null): boolean;
@@ -0,0 +1,3 @@
1
+ import type { ClaudeHooksConfig } from "./types";
2
+ export declare function getClaudeSettingsPaths(customPath?: string): string[];
3
+ export declare function loadClaudeHooksConfig(customSettingsPath?: string): Promise<ClaudeHooksConfig | null>;
@@ -0,0 +1,42 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { PluginConfig } from "./types";
3
+ export declare function createClaudeCodeHooksHook(ctx: PluginInput, config?: PluginConfig): {
4
+ "chat.message": (input: {
5
+ sessionID: string;
6
+ agent?: string;
7
+ model?: {
8
+ providerID: string;
9
+ modelID: string;
10
+ };
11
+ messageID?: string;
12
+ }, output: {
13
+ message: Record<string, unknown>;
14
+ parts: Array<{
15
+ type: string;
16
+ text?: string;
17
+ [key: string]: unknown;
18
+ }>;
19
+ }) => Promise<void>;
20
+ "tool.execute.before": (input: {
21
+ tool: string;
22
+ sessionID: string;
23
+ callID: string;
24
+ }, output: {
25
+ args: Record<string, unknown>;
26
+ }) => Promise<void>;
27
+ "tool.execute.after": (input: {
28
+ tool: string;
29
+ sessionID: string;
30
+ callID: string;
31
+ }, output: {
32
+ title: string;
33
+ output: string;
34
+ metadata: unknown;
35
+ }) => Promise<void>;
36
+ event: (input: {
37
+ event: {
38
+ type: string;
39
+ properties?: unknown;
40
+ };
41
+ }) => Promise<void>;
42
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Plugin configuration for Claude Code hooks execution
3
+ * Contains settings for hook command execution (zsh, etc.)
4
+ */
5
+ export declare const DEFAULT_CONFIG: {
6
+ forceZsh: boolean;
7
+ zshPath: string;
8
+ };
@@ -0,0 +1,40 @@
1
+ import type { ClaudeHooksConfig } from "./types";
2
+ import { type PluginExtendedConfig } from "./config-loader";
3
+ export interface PostToolUseClient {
4
+ session: {
5
+ messages: (opts: {
6
+ path: {
7
+ id: string;
8
+ };
9
+ query?: {
10
+ directory: string;
11
+ };
12
+ }) => Promise<unknown>;
13
+ };
14
+ }
15
+ export interface PostToolUseContext {
16
+ sessionId: string;
17
+ toolName: string;
18
+ toolInput: Record<string, unknown>;
19
+ toolOutput: Record<string, unknown>;
20
+ cwd: string;
21
+ transcriptPath?: string;
22
+ toolUseId?: string;
23
+ client?: PostToolUseClient;
24
+ permissionMode?: "default" | "plan" | "acceptEdits" | "bypassPermissions";
25
+ }
26
+ export interface PostToolUseResult {
27
+ block: boolean;
28
+ reason?: string;
29
+ message?: string;
30
+ warnings?: string[];
31
+ elapsedMs?: number;
32
+ hookName?: string;
33
+ toolName?: string;
34
+ additionalContext?: string;
35
+ continue?: boolean;
36
+ stopReason?: string;
37
+ suppressOutput?: boolean;
38
+ systemMessage?: string;
39
+ }
40
+ export declare function executePostToolUseHooks(ctx: PostToolUseContext, config: ClaudeHooksConfig | null, extendedConfig?: PluginExtendedConfig | null): Promise<PostToolUseResult>;
@@ -0,0 +1,25 @@
1
+ import type { PermissionDecision, ClaudeHooksConfig } from "./types";
2
+ import { type PluginExtendedConfig } from "./config-loader";
3
+ export interface PreToolUseContext {
4
+ sessionId: string;
5
+ toolName: string;
6
+ toolInput: Record<string, unknown>;
7
+ cwd: string;
8
+ transcriptPath?: string;
9
+ toolUseId?: string;
10
+ permissionMode?: "default" | "plan" | "acceptEdits" | "bypassPermissions";
11
+ }
12
+ export interface PreToolUseResult {
13
+ decision: PermissionDecision;
14
+ reason?: string;
15
+ modifiedInput?: Record<string, unknown>;
16
+ elapsedMs?: number;
17
+ hookName?: string;
18
+ toolName?: string;
19
+ inputLines?: string;
20
+ continue?: boolean;
21
+ stopReason?: string;
22
+ suppressOutput?: boolean;
23
+ systemMessage?: string;
24
+ }
25
+ export declare function executePreToolUseHooks(ctx: PreToolUseContext, config: ClaudeHooksConfig | null, extendedConfig?: PluginExtendedConfig | null): Promise<PreToolUseResult>;
@@ -0,0 +1,20 @@
1
+ import type { ClaudeHooksConfig } from "./types";
2
+ import { type PluginExtendedConfig } from "./config-loader";
3
+ export declare function setStopHookActive(sessionId: string, active: boolean): void;
4
+ export declare function getStopHookActive(sessionId: string): boolean;
5
+ export interface StopContext {
6
+ sessionId: string;
7
+ parentSessionId?: string;
8
+ cwd: string;
9
+ transcriptPath?: string;
10
+ permissionMode?: "default" | "acceptEdits" | "bypassPermissions";
11
+ stopHookActive?: boolean;
12
+ }
13
+ export interface StopResult {
14
+ block: boolean;
15
+ reason?: string;
16
+ stopHookActive?: boolean;
17
+ permissionMode?: "default" | "plan" | "acceptEdits" | "bypassPermissions";
18
+ injectPrompt?: string;
19
+ }
20
+ export declare function executeStopHooks(ctx: StopContext, config: ClaudeHooksConfig | null, extendedConfig?: PluginExtendedConfig | null): Promise<StopResult>;
@@ -0,0 +1,12 @@
1
+ import type { TodoFile } from "./types";
2
+ export declare function getTodoPath(sessionId: string): string;
3
+ export interface OpenCodeTodo {
4
+ content: string;
5
+ status: string;
6
+ priority: string;
7
+ id: string;
8
+ }
9
+ export declare function loadTodoFile(sessionId: string): TodoFile | null;
10
+ export declare function saveTodoFile(sessionId: string, file: TodoFile): void;
11
+ export declare function saveOpenCodeTodos(sessionId: string, todos: OpenCodeTodo[]): void;
12
+ export declare function deleteTodoFile(sessionId: string): void;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Caches tool_input from PreToolUse for PostToolUse
3
+ */
4
+ export declare function cacheToolInput(sessionId: string, toolName: string, invocationId: string, toolInput: Record<string, unknown>): void;
5
+ export declare function getToolInput(sessionId: string, toolName: string, invocationId: string): Record<string, unknown> | null;
@@ -0,0 +1,38 @@
1
+ import type { TranscriptEntry } from "./types";
2
+ export declare function getTranscriptPath(sessionId: string): string;
3
+ export declare function appendTranscriptEntry(sessionId: string, entry: TranscriptEntry): void;
4
+ export declare function recordToolUse(sessionId: string, toolName: string, toolInput: Record<string, unknown>): void;
5
+ export declare function recordToolResult(sessionId: string, toolName: string, toolInput: Record<string, unknown>, toolOutput: Record<string, unknown>): void;
6
+ export declare function recordUserMessage(sessionId: string, content: string): void;
7
+ export declare function recordAssistantMessage(sessionId: string, content: string): void;
8
+ /**
9
+ * Build Claude Code compatible transcript from session messages
10
+ *
11
+ * PORT FROM DISABLED: This calls client.session.messages() API to fetch
12
+ * the full session history and builds a JSONL file in Claude Code format.
13
+ *
14
+ * @param client OpenCode client instance
15
+ * @param sessionId Session ID
16
+ * @param directory Working directory
17
+ * @param currentToolName Current tool being executed (added as last entry)
18
+ * @param currentToolInput Current tool input
19
+ * @returns Temp file path (caller must call deleteTempTranscript!)
20
+ */
21
+ export declare function buildTranscriptFromSession(client: {
22
+ session: {
23
+ messages: (opts: {
24
+ path: {
25
+ id: string;
26
+ };
27
+ query?: {
28
+ directory: string;
29
+ };
30
+ }) => Promise<unknown>;
31
+ };
32
+ }, sessionId: string, directory: string, currentToolName: string, currentToolInput: Record<string, unknown>): Promise<string | null>;
33
+ /**
34
+ * Delete temp transcript file (call in finally block)
35
+ *
36
+ * PORT FROM DISABLED: Cleanup mechanism to avoid disk accumulation
37
+ */
38
+ export declare function deleteTempTranscript(path: string | null): void;