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 +85 -15
- package/README.md +93 -34
- package/dist/features/hook-message-injector/constants.d.ts +3 -0
- package/dist/features/hook-message-injector/index.d.ts +2 -0
- package/dist/features/hook-message-injector/injector.d.ts +2 -0
- package/dist/features/hook-message-injector/types.d.ts +43 -0
- package/dist/hooks/claude-code-hooks/config-loader.d.ts +12 -0
- package/dist/hooks/claude-code-hooks/config.d.ts +3 -0
- package/dist/hooks/claude-code-hooks/index.d.ts +42 -0
- package/dist/hooks/claude-code-hooks/plugin-config.d.ts +8 -0
- package/dist/hooks/claude-code-hooks/post-tool-use.d.ts +40 -0
- package/dist/hooks/claude-code-hooks/pre-tool-use.d.ts +25 -0
- package/dist/hooks/claude-code-hooks/stop.d.ts +20 -0
- package/dist/hooks/claude-code-hooks/todo.d.ts +12 -0
- package/dist/hooks/claude-code-hooks/tool-input-cache.d.ts +5 -0
- package/dist/hooks/claude-code-hooks/transcript.d.ts +38 -0
- package/dist/hooks/claude-code-hooks/types.d.ts +166 -0
- package/dist/hooks/claude-code-hooks/user-prompt-submit.d.ts +22 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/session-recovery/storage.d.ts +1 -0
- package/dist/index.js +1910 -425
- package/dist/shared/hook-disabled.d.ts +2 -0
- package/dist/shared/index.d.ts +4 -0
- package/dist/shared/pattern-matcher.d.ts +3 -0
- package/dist/shared/snake-case.d.ts +4 -0
- package/dist/shared/tool-name.d.ts +1 -0
- package/package.json +1 -1
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
|
-
|
|
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
|
-
- **
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
31
|
+
If you are a hacker, you will fucking fall in love with [OpenCode](https://github.com/sst/opencode).
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
- **
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,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,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,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;
|