🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
7.3 KiB
Contributing to Oh My OpenCode
First off, thanks for taking the time to contribute! This document provides guidelines and instructions for contributing to oh-my-opencode.
Table of Contents
- Code of Conduct
- Getting Started
- Project Structure
- Development Workflow
- Making Changes
- Pull Request Process
- Publishing
- Getting Help
Code of Conduct
Be respectful, inclusive, and constructive. We're all here to make better tools together.
Getting Started
Prerequisites
- 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
Development Setup
# 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 build
Testing Your Changes Locally
After 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.
Project Structure
oh-my-opencode/
├── src/
│ ├── agents/ # AI agents (OmO, oracle, librarian, explore, etc.)
│ ├── hooks/ # 21 lifecycle hooks
│ ├── tools/ # LSP (11), AST-Grep, Grep, Glob, etc.
│ ├── mcp/ # MCP server integrations (context7, grep_app)
│ ├── features/ # Claude Code compatibility layers
│ ├── config/ # Zod schemas and TypeScript types
│ ├── auth/ # Google Antigravity OAuth
│ ├── shared/ # Common utilities
│ └── index.ts # Main plugin entry (OhMyOpenCodePlugin)
├── script/ # Build utilities (build-schema.ts, publish.ts)
├── assets/ # JSON schema
└── dist/ # Build output (ESM + .d.ts)
Development Workflow
Build Commands
# Type check only
bun run typecheck
# Full build (ESM + TypeScript declarations + JSON schema)
bun run build
# Clean build output and rebuild
bun run rebuild
# Build schema only (after modifying src/config/schema.ts)
bun run build:schema
Code Style & Conventions
| 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
Making Changes
Adding a New Agent
- 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-sonnet-4-5",
description: "Description of what this agent does",
prompt: `Your agent's system prompt here`,
temperature: 0.1,
// ... other config
};
Adding a New Hook
- 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
},
};
}
Adding a New Tool
- 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
Adding a New MCP Server
- Create configuration in
src/mcp/ - Add to
src/mcp/index.ts - Document in README if it requires external setup
Pull Request Process
- Fork the repository and create your branch from
master - 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
PR Checklist
- Code follows project conventions
bun run typecheckpassesbun run buildsucceeds- Tested locally with OpenCode
- Updated documentation if needed (README, AGENTS.md)
- No version changes in
package.json
Publishing
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
Getting Help
- 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.