First off, thanks for taking the time to contribute! This document provides guidelines and instructions for contributing to oh-my-opencode.
- Code of Conduct
- Getting Started
- Project Structure
- Development Workflow
- Making Changes
- Pull Request Process
- Publishing
- Getting Help
Be respectful, inclusive, and constructive. We're all here to make better tools together.
English is the primary language for all communications in this repository.
This includes:
- Issues and bug reports
- Pull requests and code reviews
- Documentation and comments
- Discussions and community interactions
- Global Accessibility: English allows contributors from all regions to collaborate effectively
- Consistency: A single language keeps discussions organized and searchable
- Open Source Best Practice: Most successful open-source projects use English as the lingua franca
If English isn't your first language, don't worry! We value your contributions regardless of perfect grammar. You can:
- Use translation tools to help compose messages
- Ask for help from other community members
- Focus on clear, simple communication rather than perfect prose
- Bun (latest version) - The only supported package manager
- TypeScript 5.7.3+ - For type checking and declarations
- OpenCode 1.0.150+ - For testing the plugin
# Clone the repository
git clone https://github.com/code-yeongyu/oh-my-opencode.git
cd oh-my-opencode
# Install dependencies (bun only - never use npm/yarn)
bun install
# Build the project
bun run buildAfter making changes, you can test your local build in OpenCode:
-
Build the project:
bun run build
-
Update your OpenCode config (
~/.config/opencode/opencode.jsonoropencode.jsonc):{ "plugin": ["file:///absolute/path/to/oh-my-opencode/dist/index.js"] }For example, if your project is at
/Users/yourname/projects/oh-my-opencode:{ "plugin": ["file:///Users/yourname/projects/oh-my-opencode/dist/index.js"] }Note: Remove
"oh-my-opencode"from the plugin array if it exists, to avoid conflicts with the npm version. -
Restart OpenCode to load the changes.
-
Verify the plugin is loaded by checking for OmO agent availability or startup messages.
oh-my-opencode/
├── src/
│ ├── index.ts # Plugin entry (OhMyOpenCodePlugin)
│ ├── plugin-config.ts # JSONC multi-level config (Zod v4)
│ ├── agents/ # 11 agents (Sisyphus, Hephaestus, Oracle, Librarian, Explore, Atlas, Prometheus, Metis, Momus, Multimodal-Looker, Sisyphus-Junior)
│ ├── hooks/ # Lifecycle hooks for orchestration, recovery, UX, and context management
│ ├── tools/ # 26 tools across 15 directories
│ ├── mcp/ # 3 built-in remote MCPs (websearch, context7, grep_app)
│ ├── features/ # 19 feature modules (background-agent, skill-loader, tmux, MCP-OAuth, etc.)
│ ├── config/ # Zod v4 schema system
│ ├── shared/ # Cross-cutting utilities
│ ├── cli/ # CLI: install, run, doctor, mcp-oauth (Commander.js)
│ ├── plugin/ # 8 OpenCode hook handlers + hook composition
│ └── plugin-handlers/ # 6-phase config loading pipeline
├── packages/ # Monorepo: comment-checker, opencode-sdk
└── dist/ # Build output (ESM + .d.ts)
# Type check only
bun run typecheck
# Full build (ESM + TypeScript declarations + JSON schema)
bun run build
# Clean build output
bun run clean
# Rebuild from scratch
bun run clean && bun run build
# Build schema only (after modifying src/config/schema.ts)
bun run build:schema| Convention | Rule |
|---|---|
| Package Manager | Bun only (bun run, bun build, bunx) |
| Types | Use bun-types, not @types/node |
| Directory Naming | kebab-case (ast-grep/, claude-code-hooks/) |
| File Operations | Never use bash commands (mkdir/touch/rm) for file creation in code |
| Tool Structure | Each tool: index.ts, types.ts, constants.ts, tools.ts, utils.ts |
| Hook Pattern | createXXXHook(input: PluginInput) function naming |
| Exports | Barrel pattern (export * from "./module" in index.ts) |
Anti-Patterns (Do Not Do):
- Using npm/yarn instead of bun
- Using
@types/nodeinstead ofbun-types - Suppressing TypeScript errors with
as any,@ts-ignore,@ts-expect-error - Generic AI-generated comment bloat
- Direct
bun publish(use GitHub Actions only) - Local version modifications in
package.json
- Create a new
.tsfile insrc/agents/ - Define the agent configuration following existing patterns
- Add to
builtinAgentsinsrc/agents/index.ts - Update
src/agents/types.tsif needed - Run
bun run build:schemato update the JSON schema
// src/agents/my-agent.ts
import type { AgentConfig } from "./types";
export const myAgent: AgentConfig = {
name: "my-agent",
model: "anthropic/claude-opus-4-6",
description: "Description of what this agent does",
prompt: `Your agent's system prompt here`,
temperature: 0.1,
// ... other config
};- Create a new directory in
src/hooks/(kebab-case) - Implement
createXXXHook()function returning event handlers - Export from
src/hooks/index.ts
// src/hooks/my-hook/index.ts
import type { PluginInput } from "@opencode-ai/plugin";
export function createMyHook(input: PluginInput) {
return {
onSessionStart: async () => {
// Hook logic here
},
};
}- Create a new directory in
src/tools/with required files:index.ts- Main exportstypes.ts- TypeScript interfacesconstants.ts- Constants and tool descriptionstools.ts- Tool implementationsutils.ts- Helper functions
- Add to
builtinToolsinsrc/tools/index.ts
- Create configuration in
src/mcp/ - Add to
src/mcp/index.ts - Document in README if it requires external setup
- Fork the repository and create your branch from
dev - Make changes following the conventions above
- Build and test locally:
bun run typecheck # Ensure no type errors bun run build # Ensure build succeeds
- Test in OpenCode using the local build method described above
- Commit with clear, descriptive messages:
- Use present tense ("Add feature" not "Added feature")
- Reference issues if applicable ("Fix #123")
- Push to your fork and create a Pull Request
- Describe your changes clearly in the PR description
- Code follows project conventions
-
bun run typecheckpasses -
bun run buildsucceeds - Tested locally with OpenCode
- Updated documentation if needed (README, AGENTS.md)
- No version changes in
package.json
Important: Publishing is handled exclusively through GitHub Actions.
- Never run
bun publishdirectly (OIDC provenance issues) - Never modify
package.jsonversion locally - Maintainers use GitHub Actions workflow_dispatch:
gh workflow run publish -f bump=patch # or minor/major
- Project Knowledge: Check
AGENTS.mdfor detailed project documentation - Code Patterns: Review existing implementations in
src/ - Issues: Open an issue for bugs or feature requests
- Discussions: Start a discussion for questions or ideas
Thank you for contributing to Oh My OpenCode! Your efforts help make AI-assisted coding better for everyone.