From 359340de65f426db3e22916007fe18d8122d6ab8 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Huy <31732865+huynguyen03dev@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:23:50 +0700 Subject: [PATCH] feat: add claude_code config object to toggle Claude Code compatibility features (#23) --- README.ko.md | 26 ++++++++++++++++++++++++++ README.md | 26 ++++++++++++++++++++++++++ assets/oh-my-opencode.schema.json | 26 ++++++++++++++++++++++++++ src/config/schema.ts | 9 +++++++++ src/index.ts | 26 ++++++++++++++++++-------- 5 files changed, 105 insertions(+), 8 deletions(-) diff --git a/README.ko.md b/README.ko.md index 56c69b1..e349c62 100644 --- a/README.ko.md +++ b/README.ko.md @@ -242,6 +242,32 @@ OpenCode 는 아주 확장가능하고 아주 커스터마이저블합니다. Oh My OpenCode는 Claude Code 설정과 완벽하게 호환됩니다. Claude Code를 사용하셨다면, 기존 설정을 그대로 사용할 수 있습니다. +#### 호환성 토글 + +특정 Claude Code 호환 기능을 비활성화하려면 `claude_code` 설정 객체를 사용하세요: + +```json +{ + "claude_code": { + "mcp": false, + "commands": false, + "skills": false, + "agents": false, + "hooks": false + } +} +``` + +| 토글 | `false`일 때 로딩 비활성화 경로 | 영향 받지 않음 | +|------|-------------------------------|---------------| +| `mcp` | `~/.claude/.mcp.json`, `./.mcp.json`, `./.claude/.mcp.json` | 내장 MCP (context7, websearch_exa) | +| `commands` | `~/.claude/commands/*.md`, `./.claude/commands/*.md` | `~/.config/opencode/command/`, `./.opencode/command/` | +| `skills` | `~/.claude/skills/*/SKILL.md`, `./.claude/skills/*/SKILL.md` | - | +| `agents` | `~/.claude/agents/*.md`, `./.claude/agents/*.md` | 내장 에이전트 (oracle, librarian 등) | +| `hooks` | `~/.claude/settings.json`, `./.claude/settings.json`, `./.claude/settings.local.json` | - | + +모든 토글은 기본값이 `true` (활성화)입니다. 완전한 Claude Code 호환성을 원하면 `claude_code` 객체를 생략하세요. + #### Hooks 통합 Claude Code의 `settings.json` 훅 시스템을 통해 커스텀 스크립트를 실행합니다. Oh My OpenCode는 다음 위치의 훅을 읽고 실행합니다: diff --git a/README.md b/README.md index eb6138d..73d2ec6 100644 --- a/README.md +++ b/README.md @@ -240,6 +240,32 @@ Don't need these? Disable them via `oh-my-opencode.json`: Oh My OpenCode provides seamless Claude Code configuration compatibility. If you've been using Claude Code, your existing setup works out of the box. +#### Compatibility Toggles + +If you want to disable specific Claude Code compatibility features, use the `claude_code` configuration object: + +```json +{ + "claude_code": { + "mcp": false, + "commands": false, + "skills": false, + "agents": false, + "hooks": false + } +} +``` + +| Toggle | When `false`, disables loading from... | NOT affected | +|--------|----------------------------------------|--------------| +| `mcp` | `~/.claude/.mcp.json`, `./.mcp.json`, `./.claude/.mcp.json` | Built-in MCPs (context7, websearch_exa) | +| `commands` | `~/.claude/commands/*.md`, `./.claude/commands/*.md` | `~/.config/opencode/command/`, `./.opencode/command/` | +| `skills` | `~/.claude/skills/*/SKILL.md`, `./.claude/skills/*/SKILL.md` | - | +| `agents` | `~/.claude/agents/*.md`, `./.claude/agents/*.md` | Built-in agents (oracle, librarian, etc.) | +| `hooks` | `~/.claude/settings.json`, `./.claude/settings.json`, `./.claude/settings.local.json` | - | + +All toggles default to `true` (enabled). Omit the entire `claude_code` object for full Claude Code compatibility. + #### Hooks Integration Execute custom scripts via Claude Code's `settings.json` hook system. Oh My OpenCode reads and executes hooks defined in: diff --git a/assets/oh-my-opencode.schema.json b/assets/oh-my-opencode.schema.json index 5336c77..5857cbd 100644 --- a/assets/oh-my-opencode.schema.json +++ b/assets/oh-my-opencode.schema.json @@ -154,6 +154,32 @@ } } } + }, + "claude_code": { + "type": "object", + "description": "Toggle Claude Code compatibility features on/off. All default to true (enabled).", + "properties": { + "mcp": { + "type": "boolean", + "description": "Load MCP servers from ~/.claude/.mcp.json, ./.mcp.json, ./.claude/.mcp.json" + }, + "commands": { + "type": "boolean", + "description": "Load commands from ~/.claude/commands/*.md, ./.claude/commands/*.md" + }, + "skills": { + "type": "boolean", + "description": "Load skills from ~/.claude/skills/*/SKILL.md, ./.claude/skills/*/SKILL.md" + }, + "agents": { + "type": "boolean", + "description": "Load agents from ~/.claude/agents/*.md, ./.claude/agents/*.md" + }, + "hooks": { + "type": "boolean", + "description": "Execute hooks from ~/.claude/settings.json, ./.claude/settings.json, ./.claude/settings.local.json" + } + } } } } \ No newline at end of file diff --git a/src/config/schema.ts b/src/config/schema.ts index c567302..0c50a34 100644 --- a/src/config/schema.ts +++ b/src/config/schema.ts @@ -42,11 +42,20 @@ export const AgentOverrideConfigSchema = z.object({ export const AgentOverridesSchema = z.record(AgentNameSchema, AgentOverrideConfigSchema) +export const ClaudeCodeConfigSchema = z.object({ + mcp: z.boolean().optional(), + commands: z.boolean().optional(), + skills: z.boolean().optional(), + agents: z.boolean().optional(), + hooks: z.boolean().optional(), +}) + export const OhMyOpenCodeConfigSchema = z.object({ $schema: z.string().optional(), disabled_mcps: z.array(McpNameSchema).optional(), disabled_agents: z.array(AgentNameSchema).optional(), agents: AgentOverridesSchema.optional(), + claude_code: ClaudeCodeConfigSchema.optional(), }) export type OhMyOpenCodeConfig = z.infer diff --git a/src/index.ts b/src/index.ts index 62963d6..f6d71c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -101,6 +101,10 @@ function mergeConfigs( ...(override.disabled_mcps ?? []), ]), ], + claude_code: + override.claude_code !== undefined || base.claude_code !== undefined + ? { ...(base.claude_code ?? {}), ...(override.claude_code ?? {}) } + : undefined, }; } @@ -132,6 +136,7 @@ function loadPluginConfig(directory: string): OhMyOpenCodeConfig { agents: config.agents, disabled_agents: config.disabled_agents, disabled_mcps: config.disabled_mcps, + claude_code: config.claude_code, }); return config; } @@ -148,7 +153,9 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const directoryReadmeInjector = createDirectoryReadmeInjectorHook(ctx); const emptyTaskResponseDetector = createEmptyTaskResponseDetectorHook(ctx); const thinkMode = createThinkModeHook(); - const claudeCodeHooks = createClaudeCodeHooksHook(ctx, {}); + const claudeCodeHooks = createClaudeCodeHooksHook(ctx, { + disabledHooks: (pluginConfig.claude_code?.hooks ?? true) ? undefined : true, + }); const anthropicAutoCompact = createAnthropicAutoCompactHook(ctx); updateTerminalTitle({ sessionId: "main" }); @@ -165,8 +172,9 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { pluginConfig.disabled_agents, pluginConfig.agents, ); - const userAgents = loadUserAgents(); - const projectAgents = loadProjectAgents(); + + const userAgents = (pluginConfig.claude_code?.agents ?? true) ? loadUserAgents() : {}; + const projectAgents = (pluginConfig.claude_code?.agents ?? true) ? loadProjectAgents() : {}; config.agent = { ...builtinAgents, @@ -178,20 +186,22 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { ...config.tools, }; - const mcpResult = await loadMcpConfigs(); + const mcpResult = (pluginConfig.claude_code?.mcp ?? true) + ? await loadMcpConfigs() + : { servers: {} }; config.mcp = { ...config.mcp, ...createBuiltinMcps(pluginConfig.disabled_mcps), ...mcpResult.servers, }; - const userCommands = loadUserCommands(); + const userCommands = (pluginConfig.claude_code?.commands ?? true) ? loadUserCommands() : {}; const opencodeGlobalCommands = loadOpencodeGlobalCommands(); const systemCommands = config.command ?? {}; - const projectCommands = loadProjectCommands(); + const projectCommands = (pluginConfig.claude_code?.commands ?? true) ? loadProjectCommands() : {}; const opencodeProjectCommands = loadOpencodeProjectCommands(); - const userSkills = loadUserSkillsAsCommands(); - const projectSkills = loadProjectSkillsAsCommands(); + const userSkills = (pluginConfig.claude_code?.skills ?? true) ? loadUserSkillsAsCommands() : {}; + const projectSkills = (pluginConfig.claude_code?.skills ?? true) ? loadProjectSkillsAsCommands() : {}; config.command = { ...userCommands,