docs(agents): regenerate all AGENTS.md files with comprehensive codebase analysis

- Regenerated root AGENTS.md with overview, structure, and complexity hotspots
- Regenerated all 7 subdirectory AGENTS.md files: hooks, tools, features, agents, cli, auth, shared
- Used 11 background explore agents for comprehensive feature and architecture analysis
- All files within size limits (root: 112 lines, subdirs: 57-68 lines)
- Includes where-to-look guide, conventions, anti-patterns, and agent model information

🤖 Generated with assistance of oh-my-opencode
This commit is contained in:
YeonGyu-Kim
2026-01-02 10:42:38 +09:00
parent bebe6607d4
commit a1fe0f8517
8 changed files with 283 additions and 569 deletions

138
AGENTS.md
View File

@@ -1,30 +1,29 @@
# PROJECT KNOWLEDGE BASE # PROJECT KNOWLEDGE BASE
**Generated:** 2026-01-02T00:10:00+09:00 **Generated:** 2026-01-02T10:35:00+09:00
**Commit:** b0c39e2 **Commit:** bebe660
**Branch:** dev **Branch:** dev
## OVERVIEW ## OVERVIEW
OpenCode plugin implementing Claude Code/AmpCode features. Multi-model agent orchestration (GPT-5.2, Claude, Gemini, Grok), LSP tools (11), AST-Grep search, MCP integrations (context7, websearch_exa, grep_app). "oh-my-zsh" for OpenCode. OpenCode plugin: multi-model agent orchestration (Claude Opus 4.5, GPT-5.2, Gemini 3, Grok), 11 LSP tools, AST-Grep, Claude Code compatibility layer. "oh-my-zsh" for OpenCode.
## STRUCTURE ## STRUCTURE
``` ```
oh-my-opencode/ oh-my-opencode/
├── src/ ├── src/
│ ├── agents/ # AI agents (7): Sisyphus, oracle, librarian, explore, frontend, document-writer, multimodal-looker │ ├── agents/ # 7 AI agents - see src/agents/AGENTS.md
│ ├── hooks/ # 22 lifecycle hooks - see src/hooks/AGENTS.md │ ├── hooks/ # 22 lifecycle hooks - see src/hooks/AGENTS.md
│ ├── tools/ # LSP, AST-Grep, Grep, Glob, etc. - see src/tools/AGENTS.md │ ├── tools/ # LSP, AST-Grep, session mgmt - see src/tools/AGENTS.md
│ ├── mcp/ # MCP servers: context7, websearch_exa, grep_app │ ├── features/ # Claude Code compat layer - see src/features/AGENTS.md
│ ├── features/ # Claude Code compatibility + core features - see src/features/AGENTS.md
│ ├── config/ # Zod schema, TypeScript types
│ ├── auth/ # Google Antigravity OAuth - see src/auth/AGENTS.md │ ├── auth/ # Google Antigravity OAuth - see src/auth/AGENTS.md
│ ├── shared/ # Utilities: deep-merge, pattern-matcher, logger, etc. - see src/shared/AGENTS.md │ ├── shared/ # Cross-cutting utilities - see src/shared/AGENTS.md
│ ├── cli/ # CLI installer, doctor, run - see src/cli/AGENTS.md │ ├── cli/ # CLI installer, doctor - see src/cli/AGENTS.md
── index.ts # Main plugin entry (OhMyOpenCodePlugin) ── mcp/ # MCP configs: context7, websearch_exa, grep_app
│ ├── config/ # Zod schema, TypeScript types
│ └── index.ts # Main plugin entry (723 lines)
├── script/ # build-schema.ts, publish.ts, generate-changelog.ts ├── script/ # build-schema.ts, publish.ts, generate-changelog.ts
├── assets/ # JSON schema
└── dist/ # Build output (ESM + .d.ts) └── dist/ # Build output (ESM + .d.ts)
``` ```
@@ -32,71 +31,44 @@ oh-my-opencode/
| Task | Location | Notes | | Task | Location | Notes |
|------|----------|-------| |------|----------|-------|
| Add agent | `src/agents/` | Create .ts, add to builtinAgents in index.ts, update types.ts | | Add agent | `src/agents/` | Create .ts, add to builtinAgents, update types.ts |
| Add hook | `src/hooks/` | Create dir with createXXXHook(), export from index.ts | | Add hook | `src/hooks/` | Dir with createXXXHook(), export from index.ts |
| Add tool | `src/tools/` | Dir with index/types/constants/tools.ts, add to builtinTools | | Add tool | `src/tools/` | Dir with constants/types/tools.ts, add to builtinTools |
| Add MCP | `src/mcp/` | Create config, add to index.ts and types.ts | | Add MCP | `src/mcp/` | Create config, add to index.ts |
| Add skill | `src/features/builtin-skills/` | Create skill dir with SKILL.md | | Add skill | `src/features/builtin-skills/` | Dir with SKILL.md |
| LSP behavior | `src/tools/lsp/` | client.ts (connection), tools.ts (handlers) | | Config schema | `src/config/schema.ts` | Run `bun run build:schema` after |
| AST-Grep | `src/tools/ast-grep/` | napi.ts for @ast-grep/napi binding |
| Google OAuth | `src/auth/antigravity/` | OAuth plugin for Google/Gemini models |
| Config schema | `src/config/schema.ts` | Zod schema, run `bun run build:schema` after changes |
| Claude Code compat | `src/features/claude-code-*-loader/` | Command, skill, agent, mcp loaders | | Claude Code compat | `src/features/claude-code-*-loader/` | Command, skill, agent, mcp loaders |
| Background agents | `src/features/background-agent/` | manager.ts for task management |
| Skill MCP | `src/features/skill-mcp-manager/` | MCP servers embedded in skills |
| Interactive terminal | `src/tools/interactive-bash/` | tmux session management |
| CLI installer | `src/cli/install.ts` | Interactive TUI installation |
| Doctor checks | `src/cli/doctor/checks/` | Health checks for environment |
| Shared utilities | `src/shared/` | Cross-cutting utilities |
| Slash commands | `src/hooks/auto-slash-command/` | Auto-detect and execute `/command` patterns |
| Ralph Loop | `src/hooks/ralph-loop/` | Self-referential dev loop until completion |
## CONVENTIONS ## CONVENTIONS
- **Package manager**: Bun only (`bun run`, `bun build`, `bunx`) - **Bun only**: `bun run`, `bun test`, `bunx` (NEVER npm/npx)
- **Types**: bun-types (not @types/node) - **Types**: bun-types (not @types/node)
- **Build**: Dual output - `bun build` (ESM) + `tsc --emitDeclarationOnly` - **Build**: `bun build` (ESM) + `tsc --emitDeclarationOnly`
- **Exports**: Barrel pattern - `export * from "./module"` in index.ts - **Exports**: Barrel pattern in index.ts; explicit named exports for tools/hooks
- **Directory naming**: kebab-case (`ast-grep/`, `claude-code-hooks/`) - **Naming**: kebab-case directories, createXXXHook/createXXXTool factories
- **Tool structure**: index.ts, types.ts, constants.ts, tools.ts, utils.ts - **Testing**: BDD comments `#given`, `#when`, `#then` (same as AAA)
- **Hook pattern**: `createXXXHook(input: PluginInput)` returning event handlers - **Temperature**: 0.1 for code agents, max 0.3
- **Test style**: BDD comments `#given`, `#when`, `#then` (same as AAA)
## ANTI-PATTERNS (THIS PROJECT) ## ANTI-PATTERNS
- **npm/yarn**: Use bun exclusively | Category | Forbidden |
- **@types/node**: Use bun-types |----------|-----------|
- **Bash file ops**: Never mkdir/touch/rm/cp/mv for file creation in code | Type Safety | `as any`, `@ts-ignore`, `@ts-expect-error` |
- **Direct bun publish**: GitHub Actions workflow_dispatch only (OIDC provenance) | Package Manager | npm, yarn, npx |
- **Local version bump**: Version managed by CI workflow | File Ops | Bash mkdir/touch/rm for code file creation |
- **Year 2024**: NEVER use 2024 in code/prompts (use current year) | Publishing | Direct `bun publish`, local version bump |
- **Rush completion**: Never mark tasks complete without verification | Agent Behavior | High temp (>0.3), broad tool access, sequential agent calls |
- **Over-exploration**: Stop searching when sufficient context found | Hooks | Heavy PreToolUse logic, blocking without reason |
- **High temperature**: Don't use >0.3 for code-related agents | Year | 2024 in code/prompts (use current year) |
- **Broad tool access**: Prefer explicit `include` over unrestricted access
- **Sequential agent calls**: Use `background_task` for parallel execution
- **Heavy PreToolUse logic**: Slows every tool call
- **Self-planning for complex tasks**: Spawn planning agent (Prometheus) instead
## UNIQUE STYLES
- **Platform**: Union type `"darwin" | "linux" | "win32" | "unsupported"`
- **Optional props**: Extensive `?` for optional interface properties
- **Flexible objects**: `Record<string, unknown>` for dynamic configs
- **Error handling**: Consistent try/catch with async/await
- **Agent tools**: `tools: { include: [...] }` or `tools: { exclude: [...] }`
- **Temperature**: Most agents use `0.1` for consistency
- **Hook naming**: `createXXXHook` function convention
- **Factory pattern**: Components created via `createXXX()` functions
## AGENT MODELS ## AGENT MODELS
| Agent | Model | Purpose | | Agent | Model | Purpose |
|-------|-------|---------| |-------|-------|---------|
| Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator | | Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator |
| oracle | openai/gpt-5.2 | Strategic advisor, code review | | oracle | openai/gpt-5.2 | Strategy, code review |
| librarian | anthropic/claude-sonnet-4-5 | Multi-repo analysis, docs | | librarian | anthropic/claude-sonnet-4-5 | Docs, OSS research |
| explore | opencode/grok-code | Fast codebase exploration | | explore | opencode/grok-code | Fast codebase grep |
| frontend-ui-ux-engineer | google/gemini-3-pro-preview | UI generation | | frontend-ui-ux-engineer | google/gemini-3-pro-preview | UI generation |
| document-writer | google/gemini-3-pro-preview | Technical docs | | document-writer | google/gemini-3-pro-preview | Technical docs |
| multimodal-looker | google/gemini-3-flash | PDF/image analysis | | multimodal-looker | google/gemini-3-flash | PDF/image analysis |
@@ -107,8 +79,7 @@ oh-my-opencode/
bun run typecheck # Type check bun run typecheck # Type check
bun run build # ESM + declarations + schema bun run build # ESM + declarations + schema
bun run rebuild # Clean + Build bun run rebuild # Clean + Build
bun run build:schema # Schema only bun test # Run tests (380+)
bun test # Run tests
``` ```
## DEPLOYMENT ## DEPLOYMENT
@@ -116,37 +87,26 @@ bun test # Run tests
**GitHub Actions workflow_dispatch only** **GitHub Actions workflow_dispatch only**
1. Never modify package.json version locally 1. Never modify package.json version locally
2. Commit & push changes 2. Commit & push to dev
3. Trigger `publish` workflow: `gh workflow run publish -f bump=patch` 3. Trigger: `gh workflow run publish -f bump=patch|minor|major`
**Critical**: Never `bun publish` directly. Never bump version locally. CI auto-commits schema changes on master, maintains rolling `next` draft release on dev.
## CI PIPELINE
- **ci.yml**: Parallel test/typecheck, build verification, auto-commit schema on master, rolling `next` draft release
- **publish.yml**: Manual workflow_dispatch, version bump, changelog, OIDC npm publish
- **sisyphus-agent.yml**: Agent-in-CI for automated issue handling via `@sisyphus-dev-ai` mentions
## COMPLEXITY HOTSPOTS ## COMPLEXITY HOTSPOTS
| File | Lines | Description | | File | Lines | Description |
|------|-------|-------------| |------|-------|-------------|
| `src/index.ts` | 723 | Main plugin orchestration, all hook/tool initialization | | `src/index.ts` | 723 | Main plugin, all hook/tool init |
| `src/cli/config-manager.ts` | 669 | JSONC parsing, environment detection, installation | | `src/cli/config-manager.ts` | 669 | JSONC parsing, env detection |
| `src/auth/antigravity/fetch.ts` | 621 | Token refresh, URL rewriting, endpoint fallbacks | | `src/auth/antigravity/fetch.ts` | 621 | Token refresh, URL rewriting |
| `src/tools/lsp/client.ts` | 611 | LSP protocol, stdin/stdout buffering, JSON-RPC | | `src/tools/lsp/client.ts` | 611 | LSP protocol, JSON-RPC |
| `src/auth/antigravity/response.ts` | 598 | Response transformation, streaming | | `src/hooks/anthropic-context-window-limit-recovery/executor.ts` | 554 | Multi-stage recovery |
| `src/auth/antigravity/thinking.ts` | 571 | Thinking block extraction/transformation | | `src/agents/sisyphus.ts` | 504 | Orchestrator prompt |
| `src/hooks/anthropic-context-window-limit-recovery/executor.ts` | 554 | Session compaction, multi-stage recovery pipeline |
| `src/agents/sisyphus.ts` | 504 | Orchestrator prompt, delegation strategies |
## NOTES ## NOTES
- **Testing**: Bun native test (`bun test`), BDD-style `#given/#when/#then`, 360+ tests
- **OpenCode**: Requires >= 1.0.150 - **OpenCode**: Requires >= 1.0.150
- **Multi-lang docs**: README.md (EN), README.ko.md (KO), README.ja.md (JA), README.zh-cn.md (ZH-CN) - **Config**: `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`
- **Config**: `~/.config/opencode/oh-my-opencode.json` (user) or `.opencode/oh-my-opencode.json` (project) - **JSONC**: Config files support comments and trailing commas
- **Trusted deps**: @ast-grep/cli, @ast-grep/napi, @code-yeongyu/comment-checker - **Claude Code**: Full compat layer for settings.json hooks, commands, skills, agents, MCPs
- **JSONC support**: Config files support comments (`// comment`, `/* block */`) and trailing commas
- **Claude Code Compat**: Full compatibility layer for settings.json hooks, commands, skills, agents, MCPs
- **Skill MCP**: Skills can embed MCP server configs in YAML frontmatter - **Skill MCP**: Skills can embed MCP server configs in YAML frontmatter

View File

@@ -2,19 +2,20 @@
## OVERVIEW ## OVERVIEW
AI agent definitions for multi-model orchestration. 7 specialized agents: Sisyphus (orchestrator), oracle (strategy), librarian (research), explore (grep), frontend-ui-ux-engineer, document-writer, multimodal-looker. 7 AI agents for multi-model orchestration. Sisyphus orchestrates, specialists handle domains.
## STRUCTURE ## STRUCTURE
``` ```
agents/ agents/
├── sisyphus.ts # Primary orchestrator (Claude Opus 4.5) ├── sisyphus.ts # Primary orchestrator (504 lines)
├── oracle.ts # Strategic advisor (GPT-5.2) ├── oracle.ts # Strategic advisor
├── librarian.ts # Multi-repo research (Claude Sonnet 4.5) ├── librarian.ts # Multi-repo research
├── explore.ts # Fast codebase grep (Grok Code) ├── explore.ts # Fast codebase grep
├── frontend-ui-ux-engineer.ts # UI generation (Gemini 3 Pro) ├── frontend-ui-ux-engineer.ts # UI generation
├── document-writer.ts # Technical docs (Gemini 3 Flash) ├── document-writer.ts # Technical docs
├── multimodal-looker.ts # PDF/image analysis (Gemini 3 Flash) ├── multimodal-looker.ts # PDF/image analysis
├── sisyphus-prompt-builder.ts # Sisyphus prompt construction
├── build-prompt.ts # Shared build agent prompt ├── build-prompt.ts # Shared build agent prompt
├── plan-prompt.ts # Shared plan agent prompt ├── plan-prompt.ts # Shared plan agent prompt
├── types.ts # AgentModelConfig interface ├── types.ts # AgentModelConfig interface
@@ -24,66 +25,40 @@ agents/
## AGENT MODELS ## AGENT MODELS
| Agent | Default Model | Fallback | Purpose | | Agent | Model | Fallback | Purpose |
|-------|---------------|----------|---------| |-------|-------|----------|---------|
| Sisyphus | anthropic/claude-opus-4-5 | - | Primary orchestrator with extended thinking | | Sisyphus | anthropic/claude-opus-4-5 | - | Orchestrator with extended thinking |
| oracle | openai/gpt-5.2 | - | Architecture, debugging, code review | | oracle | openai/gpt-5.2 | - | Architecture, debugging, review |
| librarian | anthropic/claude-sonnet-4-5 | google/gemini-3-flash | Docs, OSS research, GitHub examples | | librarian | anthropic/claude-sonnet-4-5 | google/gemini-3-flash | Docs, GitHub research |
| explore | opencode/grok-code | google/gemini-3-flash, anthropic/claude-haiku-4-5 | Fast contextual grep | | explore | opencode/grok-code | gemini-3-flash, haiku-4-5 | Contextual grep |
| frontend-ui-ux-engineer | google/gemini-3-pro-preview | - | UI/UX code generation | | frontend-ui-ux-engineer | google/gemini-3-pro-preview | - | Beautiful UI code |
| document-writer | google/gemini-3-pro-preview | - | Technical writing | | document-writer | google/gemini-3-pro-preview | - | Technical writing |
| multimodal-looker | google/gemini-3-flash | - | PDF/image analysis | | multimodal-looker | google/gemini-3-flash | - | Visual analysis |
## HOW TO ADD AN AGENT ## HOW TO ADD
1. Create `src/agents/my-agent.ts`: 1. Create `src/agents/my-agent.ts`:
```typescript ```typescript
import type { AgentConfig } from "@opencode-ai/sdk"
export const myAgent: AgentConfig = { export const myAgent: AgentConfig = {
model: "provider/model-name", model: "provider/model-name",
temperature: 0.1, temperature: 0.1,
system: "Agent system prompt...", system: "...",
tools: { include: ["tool1", "tool2"] }, // or exclude: [...] tools: { include: ["tool1"] },
} }
``` ```
2. Add to `builtinAgents` in `src/agents/index.ts` 2. Add to `builtinAgents` in index.ts
3. Update `types.ts` if adding new config options 3. Update types.ts if new config options
## AGENT CONFIG OPTIONS ## MODEL FALLBACK
| Option | Type | Description | `createBuiltinAgents()` handles fallback:
|--------|------|-------------| 1. User config override
| model | string | Model identifier (provider/model-name) | 2. Installer settings (claude max20, gemini antigravity)
| temperature | number | 0.0-1.0, most use 0.1 for consistency | 3. Default model
| system | string | System prompt (can be multiline template literal) |
| tools | object | `{ include: [...] }` or `{ exclude: [...] }` |
| top_p | number | Optional nucleus sampling |
| maxTokens | number | Optional max output tokens |
## MODEL FALLBACK LOGIC ## ANTI-PATTERNS
`createBuiltinAgents()` in utils.ts handles model fallback: - High temperature (>0.3) for code agents
- Broad tool access (prefer explicit `include`)
1. Check user config override (`agents.{name}.model`) - Monolithic prompts (delegate to specialists)
2. Check installer settings (claude max20, gemini antigravity) - Missing fallbacks for rate-limited models
3. Use default model
**Fallback order for explore**:
- If gemini antigravity enabled → `google/gemini-3-flash`
- If claude max20 enabled → `anthropic/claude-haiku-4-5`
- Default → `opencode/grok-code` (free)
## ANTI-PATTERNS (AGENTS)
- **High temperature**: Don't use >0.3 for code-related agents
- **Broad tool access**: Prefer explicit `include` over unrestricted access
- **Monolithic prompts**: Keep prompts focused; delegate to specialized agents
- **Missing fallbacks**: Consider free/cheap fallbacks for rate-limited models
## SHARED PROMPTS
- **build-prompt.ts**: Base prompt for build agents (OpenCode default + Sisyphus variants)
- **plan-prompt.ts**: Base prompt for plan agents (Planner-Sisyphus)
Used by `src/index.ts` when creating Builder-Sisyphus and Planner-Sisyphus variants.

View File

@@ -2,56 +2,56 @@
## OVERVIEW ## OVERVIEW
Google Antigravity OAuth implementation for Gemini models. Token management, fetch interception, thinking block extraction, and response transformation. Google Antigravity OAuth for Gemini models. Token management, fetch interception, thinking block extraction.
## STRUCTURE ## STRUCTURE
``` ```
auth/ auth/
└── antigravity/ └── antigravity/
├── plugin.ts # Main plugin export, hooks registration ├── plugin.ts # Main export, hooks registration
├── oauth.ts # OAuth flow, token acquisition ├── oauth.ts # OAuth flow, token acquisition
├── token.ts # Token storage, refresh logic ├── token.ts # Token storage, refresh logic
├── fetch.ts # Fetch interceptor (622 lines) - URL rewriting, retry ├── fetch.ts # Fetch interceptor (621 lines)
├── response.ts # Response transformation, streaming ├── response.ts # Response transformation (598 lines)
├── thinking.ts # Thinking block extraction/transformation ├── thinking.ts # Thinking block extraction (571 lines)
├── thought-signature-store.ts # Signature caching for thinking blocks ├── thought-signature-store.ts # Signature caching
├── message-converter.ts # Message format conversion ├── message-converter.ts # Format conversion
├── request.ts # Request building, headers ├── request.ts # Request building
├── project.ts # Project ID management ├── project.ts # Project ID management
├── tools.ts # Tool registration for OAuth ├── tools.ts # OAuth tool registration
├── constants.ts # API endpoints, model mappings ├── constants.ts # API endpoints, model mappings
└── types.ts # TypeScript interfaces └── types.ts
``` ```
## KEY COMPONENTS ## KEY COMPONENTS
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `fetch.ts` | Core interceptor - rewrites URLs, manages tokens, handles retries | | fetch.ts | URL rewriting, token injection, retries |
| `thinking.ts` | Extracts `<antThinking>` blocks, transforms for OpenCode compatibility | | thinking.ts | Extract `<antThinking>` blocks |
| `response.ts` | Handles streaming responses, SSE parsing | | response.ts | Streaming SSE parsing |
| `oauth.ts` | Browser-based OAuth flow for Google accounts | | oauth.ts | Browser-based OAuth flow |
| `token.ts` | Token persistence, expiry checking, refresh | | token.ts | Token persistence, expiry |
## HOW IT WORKS ## HOW IT WORKS
1. **Intercept**: `fetch.ts` intercepts requests to Anthropic/Google endpoints 1. **Intercept**: fetch.ts intercepts Anthropic/Google requests
2. **Rewrite**: URLs rewritten to Antigravity proxy endpoints 2. **Rewrite**: URLs Antigravity proxy endpoints
3. **Auth**: Bearer token injected from stored OAuth credentials 3. **Auth**: Bearer token from stored OAuth credentials
4. **Response**: Streaming responses parsed, thinking blocks extracted 4. **Response**: Streaming parsed, thinking blocks extracted
5. **Transform**: Response format normalized for OpenCode consumption 5. **Transform**: Normalized for OpenCode
## ANTI-PATTERNS (AUTH) ## FEATURES
- **Direct API calls**: Always go through fetch interceptor - Multi-account (up to 10 Google accounts)
- **Storing tokens in code**: Use `token.ts` storage layer - Auto-fallback on rate limit
- **Ignoring refresh**: Check token expiry before requests - Thinking blocks preserved
- **Blocking on OAuth**: OAuth flow is async, never block main thread - Antigravity proxy for AI Studio access
## NOTES ## ANTI-PATTERNS
- **Multi-account**: Supports up to 10 Google accounts for load balancing - Direct API calls (use fetch interceptor)
- **Fallback**: On rate limit, automatically switches to next available account - Tokens in code (use token.ts storage)
- **Thinking blocks**: Preserved and transformed for extended thinking features - Ignoring refresh (check expiry first)
- **Proxy**: Uses Antigravity proxy for Google AI Studio access - Blocking on OAuth (always async)

View File

@@ -2,92 +2,67 @@
## OVERVIEW ## OVERVIEW
Command-line interface for oh-my-opencode. Interactive installer, health diagnostics (doctor), and runtime commands. Entry point: `bunx oh-my-opencode`. CLI for oh-my-opencode: interactive installer, health diagnostics (doctor), runtime launcher. Entry: `bunx oh-my-opencode`.
## STRUCTURE ## STRUCTURE
``` ```
cli/ cli/
├── index.ts # Commander.js entry point, subcommand routing ├── index.ts # Commander.js entry, subcommand routing
├── install.ts # Interactive TUI installer ├── install.ts # Interactive TUI installer (477 lines)
├── config-manager.ts # Config detection, parsing, merging (669 lines) ├── config-manager.ts # JSONC parsing, env detection (669 lines)
├── types.ts # CLI-specific types ├── types.ts # CLI-specific types
├── doctor/ # Health check system ├── doctor/ # Health check system
│ ├── index.ts # Doctor command entry │ ├── index.ts # Doctor command entry
│ ├── constants.ts # Check categories, descriptions │ ├── constants.ts # Check categories
│ ├── types.ts # Check result interfaces │ ├── types.ts # Check result interfaces
│ └── checks/ # 17 individual health checks │ └── checks/ # 17+ individual checks
├── get-local-version/ # Version detection utility ├── get-local-version/ # Version detection
│ ├── index.ts
│ └── formatter.ts
└── run/ # OpenCode session launcher └── run/ # OpenCode session launcher
├── index.ts
└── completion.test.ts
``` ```
## CLI COMMANDS ## CLI COMMANDS
| Command | Purpose | Key File | | Command | Purpose |
|---------|---------|----------| |---------|---------|
| `install` | Interactive setup wizard | `install.ts` | | `install` | Interactive setup wizard |
| `doctor` | Environment health checks | `doctor/index.ts` | | `doctor` | Environment health checks |
| `run` | Launch OpenCode session | `run/index.ts` | | `run` | Launch OpenCode session |
## DOCTOR CHECKS ## DOCTOR CHECKS
17 checks in `doctor/checks/`: 17+ checks in `doctor/checks/`:
- version.ts (OpenCode >= 1.0.150)
- config.ts (plugin registered)
- bun.ts, node.ts, git.ts
- anthropic-auth.ts, openai-auth.ts, google-auth.ts
- lsp-*.ts, mcp-*.ts
| Check | Validates | ## CONFIG-MANAGER (669 lines)
|-------|-----------|
| `version.ts` | OpenCode version >= 1.0.150 |
| `config.ts` | Plugin registered in opencode.json |
| `bun.ts` | Bun runtime available |
| `node.ts` | Node.js version compatibility |
| `git.ts` | Git installed |
| `anthropic-auth.ts` | Claude authentication |
| `openai-auth.ts` | OpenAI authentication |
| `google-auth.ts` | Google/Gemini authentication |
| `lsp-*.ts` | Language server availability |
| `mcp-*.ts` | MCP server connectivity |
## INSTALLATION FLOW - JSONC support (comments, trailing commas)
- Multi-source: User (~/.config/opencode/) + Project (.opencode/)
- Zod validation
- Legacy format migration
- Error aggregation for doctor
1. **Detection**: Find existing `opencode.json` / `opencode.jsonc` ## HOW TO ADD CHECK
2. **TUI Prompts**: Claude subscription? ChatGPT? Gemini?
3. **Config Generation**: Build `oh-my-opencode.json` based on answers
4. **Plugin Registration**: Add to `plugin` array in opencode.json
5. **Auth Guidance**: Instructions for `opencode auth login`
## CONFIG-MANAGER
The largest file (669 lines) handles:
- **JSONC support**: Parses comments and trailing commas
- **Multi-source detection**: User (~/.config/opencode/) + Project (.opencode/)
- **Schema validation**: Zod-based config validation
- **Migration**: Handles legacy config formats
- **Error collection**: Aggregates parsing errors for doctor
## HOW TO ADD A DOCTOR CHECK
1. Create `src/cli/doctor/checks/my-check.ts`: 1. Create `src/cli/doctor/checks/my-check.ts`:
```typescript ```typescript
import type { DoctorCheck } from "../types"
export const myCheck: DoctorCheck = { export const myCheck: DoctorCheck = {
name: "my-check", name: "my-check",
category: "environment", category: "environment",
check: async () => { check: async () => {
// Return { status: "pass" | "warn" | "fail", message: string } return { status: "pass" | "warn" | "fail", message: "..." }
} }
} }
``` ```
2. Add to `src/cli/doctor/checks/index.ts` 2. Add to `src/cli/doctor/checks/index.ts`
3. Update `constants.ts` if new category
## ANTI-PATTERNS (CLI) ## ANTI-PATTERNS
- **Blocking prompts in non-TTY**: Check `process.stdout.isTTY` before TUI - Blocking prompts in non-TTY (check `process.stdout.isTTY`)
- **Hardcoded paths**: Use shared utilities for config paths - Hardcoded paths (use shared utilities)
- **Ignoring JSONC**: User configs may have comments - JSON.parse for user files (use parseJsonc)
- **Silent failures**: Doctor checks must return clear status/message - Silent failures in doctor checks

View File

@@ -2,207 +2,65 @@
## OVERVIEW ## OVERVIEW
Claude Code compatibility layer and core feature modules. Enables Claude Code configs/commands/skills/MCPs/hooks to work seamlessly in OpenCode. Claude Code compatibility layer + core feature modules. Commands, skills, agents, MCPs, hooks from Claude Code work seamlessly.
## STRUCTURE ## STRUCTURE
``` ```
features/ features/
├── background-agent/ # Background task management ├── background-agent/ # Task lifecycle, notifications (460 lines)
│ ├── manager.ts # Task lifecycle, notifications ├── builtin-commands/ # Built-in slash commands
│ ├── manager.test.ts ├── builtin-skills/ # Built-in skills (playwright)
│ └── types.ts ├── claude-code-agent-loader/ # ~/.claude/agents/*.md
├── builtin-commands/ # Built-in slash command definitions ├── claude-code-command-loader/ # ~/.claude/commands/*.md
├── builtin-skills/ # Built-in skills (playwright, etc.) ├── claude-code-mcp-loader/ # .mcp.json files
│ └── */SKILL.md # Each skill in own directory
├── claude-code-agent-loader/ # Load agents from ~/.claude/agents/*.md
├── claude-code-command-loader/ # Load commands from ~/.claude/commands/*.md
├── claude-code-mcp-loader/ # Load MCPs from .mcp.json
│ └── env-expander.ts # ${VAR} expansion │ └── env-expander.ts # ${VAR} expansion
├── claude-code-plugin-loader/ # Load external plugins from installed_plugins.json ├── claude-code-plugin-loader/ # installed_plugins.json (484 lines)
├── claude-code-session-state/ # Session state persistence ├── claude-code-session-state/ # Session state persistence
├── opencode-skill-loader/ # Load skills from OpenCode and Claude paths ├── opencode-skill-loader/ # Skills from OpenCode + Claude paths
├── skill-mcp-manager/ # MCP servers embedded in skills ├── skill-mcp-manager/ # MCP servers in skill YAML
│ ├── manager.ts # Lazy-loading MCP client lifecycle
│ └── types.ts
└── hook-message-injector/ # Inject messages into conversation └── hook-message-injector/ # Inject messages into conversation
``` ```
## LOADER PRIORITY ## LOADER PRIORITY
Each loader reads from multiple directories (highest priority first): | Loader | Priority (highest first) |
|--------|--------------------------|
| Loader | Priority Order |
|--------|---------------|
| Commands | `.opencode/command/` > `~/.config/opencode/command/` > `.claude/commands/` > `~/.claude/commands/` | | Commands | `.opencode/command/` > `~/.config/opencode/command/` > `.claude/commands/` > `~/.claude/commands/` |
| Skills | `.opencode/skill/` > `~/.config/opencode/skill/` > `.claude/skills/` > `~/.claude/skills/` | | Skills | `.opencode/skill/` > `~/.config/opencode/skill/` > `.claude/skills/` > `~/.claude/skills/` |
| Agents | `.claude/agents/` > `~/.claude/agents/` | | Agents | `.claude/agents/` > `~/.claude/agents/` |
| MCPs | `.claude/.mcp.json` > `.mcp.json` > `~/.claude/.mcp.json` | | MCPs | `.claude/.mcp.json` > `.mcp.json` > `~/.claude/.mcp.json` |
## HOW TO ADD A LOADER
1. Create directory: `src/features/claude-code-my-loader/`
2. Create files:
- `loader.ts`: Main loader logic with `load()` function
- `types.ts`: TypeScript interfaces
- `index.ts`: Barrel export
3. Pattern: Read from multiple dirs, merge with priority, return normalized config
## BACKGROUND AGENT SPECIFICS
- **Task lifecycle**: pending → running → completed/failed
- **Notifications**: OS notification on task complete (configurable)
- **Result retrieval**: `background_output` tool with task_id
- **Cancellation**: `background_cancel` with task_id or all=true
## CONFIG TOGGLES ## CONFIG TOGGLES
Disable features in `oh-my-opencode.json`:
```json ```json
{ {
"claude_code": { "claude_code": {
"mcp": false, // Skip .mcp.json loading "mcp": false, // Skip .mcp.json
"commands": false, // Skip commands/*.md loading "commands": false, // Skip commands/*.md
"skills": false, // Skip skills/*/SKILL.md loading "skills": false, // Skip skills/*/SKILL.md
"agents": false, // Skip agents/*.md loading "agents": false, // Skip agents/*.md
"hooks": false // Skip settings.json hooks "hooks": false // Skip settings.json hooks
} }
} }
``` ```
## HOOK MESSAGE INJECTOR ## BACKGROUND AGENT
- **Purpose**: Inject system messages into conversation at specific points - Lifecycle: pending → running → completed/failed
- **Timing**: PreToolUse, PostToolUse, UserPromptSubmit, Stop - OS notification on complete
- **Format**: Returns `{ messages: [{ role: "user", content: "..." }] }` - `background_output` to retrieve results
- `background_cancel` with task_id or all=true
## MCP LOADER (claude-code-mcp-loader) ## SKILL MCP
Loads MCP server configs from `.mcp.json` files. Full Claude Code compatibility. - MCP servers embedded in skill YAML frontmatter
- Lazy client loading, session-scoped cleanup
- `skill_mcp` tool exposes capabilities
### File Locations (Priority Order) ## ANTI-PATTERNS
| Path | Scope | Description | - Blocking on load (loaders run at startup)
|------|-------|-------------| - No error handling (always try/catch)
| `~/.claude/.mcp.json` | user | User-global MCP servers | - Ignoring priority order
| `./.mcp.json` | project | Project-specific MCP servers | - Writing to ~/.claude/ (read-only)
| `./.claude/.mcp.json` | local | Local overrides (git-ignored) |
### .mcp.json Format
```json
{
"mcpServers": {
"server-name": {
"type": "stdio|http|sse",
"command": "npx",
"args": ["-y", "@anthropics/mcp-server-example"],
"env": {
"API_KEY": "${MY_API_KEY}"
},
"disabled": false
}
}
}
```
### Server Types
| Type | Required Fields | Description |
|------|-----------------|-------------|
| `stdio` (default) | `command`, `args?`, `env?` | Local subprocess MCP |
| `http` | `url`, `headers?` | HTTP-based remote MCP |
| `sse` | `url`, `headers?` | SSE-based remote MCP |
### Environment Variable Expansion
Supports `${VAR}` syntax in all string fields:
```json
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["${HOME}/mcp-server/index.js"],
"env": {
"API_KEY": "${MY_API_KEY}",
"DEBUG": "${DEBUG:-false}"
}
}
}
}
```
### Examples
**stdio (Local subprocess)**:
```json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@anthropics/mcp-server-filesystem", "/path/to/dir"]
}
}
}
```
**http (Remote)**:
```json
{
"mcpServers": {
"remote-api": {
"type": "http",
"url": "https://mcp.example.com/api",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}
```
**Disable a server**:
```json
{
"mcpServers": {
"expensive-server": {
"command": "...",
"disabled": true
}
}
}
```
### Transformation
Claude Code format → OpenCode format:
| Claude Code | OpenCode |
|-------------|----------|
| `type: "stdio"` | `type: "local"` |
| `type: "http\|sse"` | `type: "remote"` |
| `command` + `args` | `command: [cmd, ...args]` |
| `env` | `environment` |
| `headers` | `headers` |
## SKILL MCP MANAGER
- **Purpose**: Manage MCP servers embedded in skill YAML frontmatter
- **Lifecycle**: Lazy client loading, session-scoped cleanup
- **Config**: `mcp` field in skill's YAML frontmatter defines server config
- **Tool**: `skill_mcp` exposes MCP capabilities (tools, resources, prompts)
## BUILTIN SKILLS
- **Location**: `src/features/builtin-skills/*/SKILL.md`
- **Available**: `playwright` (browser automation)
- **Disable**: `disabled_skills: ["playwright"]` in config
## ANTI-PATTERNS (FEATURES)
- **Blocking on load**: Loaders run at startup, keep them fast
- **No error handling**: Always try/catch, log failures, return empty on error
- **Ignoring priority**: Higher priority dirs must override lower
- **Modifying user files**: Loaders read-only, never write to ~/.claude/

View File

@@ -2,85 +2,65 @@
## OVERVIEW ## OVERVIEW
Lifecycle hooks that intercept/modify agent behavior. Inject context, enforce rules, recover from errors, notify on events. 22 lifecycle hooks intercepting/modifying agent behavior. Context injection, error recovery, output control, notifications.
## STRUCTURE ## STRUCTURE
``` ```
hooks/ hooks/
├── agent-usage-reminder/ # Remind to use specialized agents ├── anthropic-context-window-limit-recovery/ # Auto-compact at token limit (554 lines)
├── anthropic-context-window-limit-recovery/ # Auto-compact Claude at token limit ├── auto-slash-command/ # Detect and execute /command patterns
├── auto-slash-command/ # Auto-detect and execute /command patterns ├── auto-update-checker/ # Version notifications, startup toast
├── auto-update-checker/ # Version update notifications ├── background-notification/ # OS notify on task complete
├── background-notification/ # OS notify on background task complete ├── claude-code-hooks/ # settings.json PreToolUse/PostToolUse/etc
├── claude-code-hooks/ # Claude Code settings.json integration
├── comment-checker/ # Prevent excessive AI comments ├── comment-checker/ # Prevent excessive AI comments
── filters/ # Filtering rules (docstring, directive, bdd, etc.) ── filters/ # docstring, directive, bdd, etc
│ └── output/ # Output formatting ├── compaction-context-injector/ # Preserve context during compaction
├── compaction-context-injector/ # Inject context during compaction ├── directory-agents-injector/ # Auto-inject AGENTS.md
├── directory-agents-injector/ # Auto-inject AGENTS.md files ├── directory-readme-injector/ # Auto-inject README.md
├── directory-readme-injector/ # Auto-inject README.md files
├── empty-message-sanitizer/ # Sanitize empty messages ├── empty-message-sanitizer/ # Sanitize empty messages
├── interactive-bash-session/ # Tmux session management ├── interactive-bash-session/ # Tmux session management
├── keyword-detector/ # Detect ultrawork/search keywords ├── keyword-detector/ # ultrawork/search keyword activation
├── non-interactive-env/ # CI/headless environment handling ├── non-interactive-env/ # CI/headless handling
├── preemptive-compaction/ # Pre-emptive session compaction ├── preemptive-compaction/ # Pre-emptive at 85% usage
├── ralph-loop/ # Self-referential dev loop until completion ├── ralph-loop/ # Self-referential dev loop
├── rules-injector/ # Conditional rules from .claude/rules/ ├── rules-injector/ # Conditional rules from .claude/rules/
├── session-recovery/ # Recover from session errors ├── session-recovery/ # Recover from errors (430 lines)
├── think-mode/ # Auto-detect thinking triggers ├── think-mode/ # Auto-detect thinking triggers
├── thinking-block-validator/ # Validate thinking blocks in messages ├── agent-usage-reminder/ # Remind to use specialists
├── context-window-monitor.ts # Monitor context usage (standalone) ├── context-window-monitor.ts # Monitor usage (standalone)
├── empty-task-response-detector.ts ├── session-notification.ts # OS notify on idle
├── session-notification.ts # OS notify on idle (standalone) ├── todo-continuation-enforcer.ts # Force TODO completion
── todo-continuation-enforcer.ts # Force TODO completion (standalone) ── tool-output-truncator.ts # Truncate verbose outputs
└── tool-output-truncator.ts # Truncate verbose outputs (standalone)
``` ```
## HOOK CATEGORIES
| Category | Hooks | Purpose |
|----------|-------|---------|
| Context Injection | directory-agents-injector, directory-readme-injector, rules-injector, compaction-context-injector | Auto-inject relevant context |
| Session Management | session-recovery, anthropic-context-window-limit-recovery, preemptive-compaction, empty-message-sanitizer | Handle session lifecycle |
| Output Control | comment-checker, tool-output-truncator | Control agent output quality |
| Notifications | session-notification, background-notification, auto-update-checker | OS/user notifications |
| Behavior Enforcement | todo-continuation-enforcer, keyword-detector, think-mode, agent-usage-reminder | Enforce agent behavior |
| Environment | non-interactive-env, interactive-bash-session, context-window-monitor | Adapt to runtime environment |
| Compatibility | claude-code-hooks | Claude Code settings.json support |
## HOW TO ADD A HOOK
1. Create directory: `src/hooks/my-hook/`
2. Create files:
- `index.ts`: Export `createMyHook(input: PluginInput)`
- `constants.ts`: Hook name constant
- `types.ts`: TypeScript interfaces (optional)
- `storage.ts`: Persistent state (optional)
3. Return event handlers: `{ PreToolUse?, PostToolUse?, UserPromptSubmit?, Stop?, onSummarize? }`
4. Export from `src/hooks/index.ts`
5. Register in main plugin
## HOOK EVENTS ## HOOK EVENTS
| Event | Timing | Can Block | Use Case | | Event | Timing | Can Block | Use Case |
|-------|--------|-----------|----------| |-------|--------|-----------|----------|
| PreToolUse | Before tool exec | Yes | Validate, modify input | | PreToolUse | Before tool | Yes | Validate, modify input |
| PostToolUse | After tool exec | No | Add context, warnings | | PostToolUse | After tool | No | Add context, warnings |
| UserPromptSubmit | On user prompt | Yes | Inject messages, block | | UserPromptSubmit | On prompt | Yes | Inject messages, block |
| Stop | Session idle | No | Inject follow-ups | | Stop | Session idle | No | Inject follow-ups |
| onSummarize | During compaction | No | Preserve critical context | | onSummarize | Compaction | No | Preserve context |
## COMMON PATTERNS ## HOW TO ADD
- **Storage**: Use `storage.ts` with JSON file for persistent state across sessions 1. Create `src/hooks/my-hook/`
- **Once-per-session**: Track injected paths in Set to avoid duplicate injection 2. Files: `index.ts` (createMyHook), `constants.ts`, `types.ts` (optional)
- **Message injection**: Return `{ messages: [...] }` from event handlers 3. Return: `{ PreToolUse?, PostToolUse?, UserPromptSubmit?, Stop?, onSummarize? }`
- **Blocking**: Return `{ blocked: true, message: "reason" }` from PreToolUse 4. Export from `src/hooks/index.ts`
## ANTI-PATTERNS (HOOKS) ## PATTERNS
- **Heavy computation** in PreToolUse: Slows every tool call - **Storage**: JSON file for persistent state across sessions
- **Blocking without clear reason**: Always provide actionable message - **Once-per-session**: Track injected paths in Set
- **Duplicate injection**: Track what's already injected per session - **Message injection**: Return `{ messages: [...] }`
- **Ignoring errors**: Always try/catch, log failures, don't crash session - **Blocking**: Return `{ blocked: true, message: "..." }` from PreToolUse
## ANTI-PATTERNS
- Heavy computation in PreToolUse (slows every tool call)
- Blocking without actionable message
- Duplicate injection (track what's injected)
- Missing try/catch (don't crash session)

View File

@@ -2,81 +2,62 @@
## OVERVIEW ## OVERVIEW
Cross-cutting utility functions used across agents, hooks, tools, and features. Path resolution, config management, text processing, and Claude Code compatibility helpers. Cross-cutting utilities: path resolution, config management, text processing, Claude Code compatibility helpers.
## STRUCTURE ## STRUCTURE
``` ```
shared/ shared/
├── index.ts # Barrel export (import { x } from "../shared") ├── index.ts # Barrel export
├── claude-config-dir.ts # Resolve ~/.claude directory ├── claude-config-dir.ts # ~/.claude resolution
├── command-executor.ts # Shell command execution with variable expansion ├── command-executor.ts # Shell exec with variable expansion
├── config-errors.ts # Global config error tracking ├── config-errors.ts # Global error tracking
├── config-path.ts # User/project config path resolution ├── config-path.ts # User/project config paths
├── data-path.ts # XDG data directory resolution ├── data-path.ts # XDG data directory
├── deep-merge.ts # Type-safe recursive object merging ├── deep-merge.ts # Type-safe recursive merge
├── dynamic-truncator.ts # Token-aware output truncation ├── dynamic-truncator.ts # Token-aware truncation
├── file-reference-resolver.ts # @filename syntax resolution ├── file-reference-resolver.ts # @filename syntax
├── file-utils.ts # Symlink resolution, markdown detection ├── file-utils.ts # Symlink, markdown detection
├── frontmatter.ts # YAML frontmatter parsing ├── frontmatter.ts # YAML frontmatter parsing
├── hook-disabled.ts # Check if hook is disabled in config ├── hook-disabled.ts # Check if hook disabled
├── jsonc-parser.ts # JSON with Comments parsing ├── jsonc-parser.ts # JSON with Comments
├── logger.ts # File-based logging to OS temp ├── logger.ts # File-based logging
├── migration.ts # Legacy name compatibility (omo -> Sisyphus) ├── migration.ts # Legacy name compat (omo Sisyphus)
├── model-sanitizer.ts # Normalize model names ├── model-sanitizer.ts # Normalize model names
├── pattern-matcher.ts # Tool name matching with wildcards ├── pattern-matcher.ts # Tool name matching
├── snake-case.ts # Case conversion for objects ├── snake-case.ts # Case conversion
└── tool-name.ts # Normalize tool names to PascalCase └── tool-name.ts # PascalCase normalization
``` ```
## UTILITY CATEGORIES ## WHEN TO USE
| Category | Utilities | Used By | | Task | Utility |
|----------|-----------|---------| |------|---------|
| Path Resolution | `getClaudeConfigDir`, `getUserConfigPath`, `getProjectConfigPath`, `getDataDir` | Features, Hooks | | Find ~/.claude | `getClaudeConfigDir()` |
| Config Management | `deepMerge`, `parseJsonc`, `isHookDisabled`, `configErrors` | index.ts, CLI | | Merge configs | `deepMerge(base, override)` |
| Text Processing | `resolveCommandsInText`, `resolveFileReferencesInText`, `parseFrontmatter` | Commands, Rules | | Parse user files | `parseJsonc()` |
| Output Control | `dynamicTruncate` | Tools (Grep, LSP) | | Check hook enabled | `isHookDisabled(name, list)` |
| Normalization | `transformToolName`, `objectToSnakeCase`, `sanitizeModelName` | Hooks, Agents | | Truncate output | `dynamicTruncate(text, budget)` |
| Compatibility | `migration.ts` | Config loading | | Resolve @file | `resolveFileReferencesInText()` |
| Execute shell | `resolveCommandsInText()` |
## WHEN TO USE WHAT | Legacy names | `migrateLegacyAgentNames()` |
| Task | Utility | Notes |
|------|---------|-------|
| Find Claude Code configs | `getClaudeConfigDir()` | Never hardcode `~/.claude` |
| Merge settings (default → user → project) | `deepMerge(base, override)` | Arrays replaced, objects merged |
| Parse user config files | `parseJsonc()` | Supports comments and trailing commas |
| Check if hook should run | `isHookDisabled(name, disabledHooks)` | Respects `disabled_hooks` config |
| Truncate large tool output | `dynamicTruncate(text, budget, reserved)` | Token-aware, prevents overflow |
| Resolve `@file` references | `resolveFileReferencesInText()` | maxDepth=3 prevents infinite loops |
| Execute shell commands | `resolveCommandsInText()` | Supports `!`\`command\`\` syntax |
| Handle legacy agent names | `migrateLegacyAgentNames()` | `omo``Sisyphus` |
## CRITICAL PATTERNS ## CRITICAL PATTERNS
### Dynamic Truncation
```typescript ```typescript
import { dynamicTruncate } from "../shared" // Dynamic truncation
// Keep 50% headroom, max 50k tokens
const output = dynamicTruncate(result, remainingTokens, 0.5) const output = dynamicTruncate(result, remainingTokens, 0.5)
```
### Deep Merge Priority // Deep merge priority
```typescript const final = deepMerge(deepMerge(defaults, userConfig), projectConfig)
const final = deepMerge(defaults, userConfig)
final = deepMerge(final, projectConfig) // Project wins
```
### Safe JSONC Parsing // Safe JSONC
```typescript
const { config, error } = parseJsoncSafe(content) const { config, error } = parseJsoncSafe(content)
if (error) return fallback
``` ```
## ANTI-PATTERNS (SHARED) ## ANTI-PATTERNS
- **Hardcoding paths**: Use `getClaudeConfigDir()`, `getUserConfigPath()` - Hardcoding paths (use getClaudeConfigDir, getUserConfigPath)
- **Manual JSON.parse**: Use `parseJsonc()` for user files (comments allowed) - JSON.parse for user files (use parseJsonc)
- **Ignoring truncation**: Large outputs MUST use `dynamicTruncate` - Ignoring truncation (large outputs MUST use dynamicTruncate)
- **Direct string concat for configs**: Use `deepMerge` for proper priority - Direct string concat for configs (use deepMerge)

View File

@@ -2,33 +2,26 @@
## OVERVIEW ## OVERVIEW
Custom tools extending agent capabilities: LSP integration (11 tools), AST-aware code search/replace, file operations with timeouts, background task management. Custom tools: 11 LSP tools, AST-aware search/replace, file ops with timeouts, background task management, session navigation.
## STRUCTURE ## STRUCTURE
``` ```
tools/ tools/
├── ast-grep/ # AST-aware code search/replace (25 languages) ├── ast-grep/ # AST-aware code search/replace (25 languages)
│ ├── cli.ts # @ast-grep/cli subprocess │ ├── napi.ts # @ast-grep/napi binding (preferred)
── napi.ts # @ast-grep/napi native binding (preferred) ── cli.ts # @ast-grep/cli fallback
│ ├── constants.ts, types.ts, tools.ts, utils.ts
├── background-task/ # Async agent task management ├── background-task/ # Async agent task management
├── call-omo-agent/ # Spawn explore/librarian agents ├── call-omo-agent/ # Spawn explore/librarian agents
├── glob/ # File pattern matching (timeout-safe) ├── glob/ # File pattern matching (60s timeout)
├── grep/ # Content search (timeout-safe) ├── grep/ # Content search (60s timeout)
├── interactive-bash/ # Tmux session management ├── interactive-bash/ # Tmux session management
├── look-at/ # Multimodal analysis (PDF, images) ├── look-at/ # Multimodal analysis (PDF, images)
├── lsp/ # 11 LSP tools ├── lsp/ # 11 LSP tools (611 lines client.ts)
│ ├── client.ts # LSP connection lifecycle │ ├── client.ts # LSP connection lifecycle
│ ├── config.ts # Server configurations │ ├── config.ts # Server configurations
│ ├── tools.ts # Tool implementations
│ └── types.ts
├── session-manager/ # OpenCode session file management
│ ├── constants.ts # Storage paths, descriptions
│ ├── types.ts # Session data interfaces
│ ├── storage.ts # File I/O operations
│ ├── utils.ts # Formatting, filtering
│ └── tools.ts # Tool implementations │ └── tools.ts # Tool implementations
├── session-manager/ # OpenCode session file ops
├── skill/ # Skill loading and execution ├── skill/ # Skill loading and execution
├── skill-mcp/ # Skill-embedded MCP invocation ├── skill-mcp/ # Skill-embedded MCP invocation
├── slashcommand/ # Slash command execution ├── slashcommand/ # Slash command execution
@@ -37,47 +30,39 @@ tools/
## TOOL CATEGORIES ## TOOL CATEGORIES
| Category | Tools | Purpose | | Category | Tools |
|----------|-------|---------| |----------|-------|
| LSP | lsp_hover, lsp_goto_definition, lsp_find_references, lsp_document_symbols, lsp_workspace_symbols, lsp_diagnostics, lsp_servers, lsp_prepare_rename, lsp_rename, lsp_code_actions, lsp_code_action_resolve | IDE-like code intelligence | | LSP | lsp_hover, lsp_goto_definition, lsp_find_references, lsp_document_symbols, lsp_workspace_symbols, lsp_diagnostics, lsp_servers, lsp_prepare_rename, lsp_rename, lsp_code_actions, lsp_code_action_resolve |
| AST | ast_grep_search, ast_grep_replace | Pattern-based code search/replace | | AST | ast_grep_search, ast_grep_replace |
| File Search | grep, glob | Content and file pattern matching | | File Search | grep, glob |
| Session | session_list, session_read, session_search, session_info | OpenCode session file management | | Session | session_list, session_read, session_search, session_info |
| Background | background_task, background_output, background_cancel | Async agent orchestration | | Background | background_task, background_output, background_cancel |
| Multimodal | look_at | PDF/image analysis via Gemini | | Multimodal | look_at |
| Terminal | interactive_bash | Tmux session control | | Terminal | interactive_bash |
| Commands | slashcommand | Execute slash commands | | Skills | skill, skill_mcp |
| Skills | skill, skill_mcp | Load skills, invoke skill-embedded MCPs | | Agents | call_omo_agent |
| Agents | call_omo_agent | Spawn explore/librarian |
## HOW TO ADD A TOOL ## HOW TO ADD
1. Create directory: `src/tools/my-tool/` 1. Create `src/tools/my-tool/`
2. Create files: 2. Files: `constants.ts`, `types.ts`, `tools.ts`, `index.ts`
- `constants.ts`: `TOOL_NAME`, `TOOL_DESCRIPTION`
- `types.ts`: Parameter/result interfaces
- `tools.ts`: Tool implementation (returns OpenCode tool object)
- `index.ts`: Barrel export
- `utils.ts`: Helpers (optional)
3. Add to `builtinTools` in `src/tools/index.ts` 3. Add to `builtinTools` in `src/tools/index.ts`
## LSP SPECIFICS ## LSP SPECIFICS
- **Client lifecycle**: Lazy init on first use, auto-shutdown on idle - Lazy init on first use, auto-shutdown on idle
- **Config priority**: opencode.json > oh-my-opencode.json > defaults - Config priority: opencode.json > oh-my-opencode.json > defaults
- **Supported servers**: typescript-language-server, pylsp, gopls, rust-analyzer, etc. - Servers: typescript-language-server, pylsp, gopls, rust-analyzer
- **Custom servers**: Add via `lsp` config in oh-my-opencode.json
## AST-GREP SPECIFICS ## AST-GREP SPECIFICS
- **Meta-variables**: `$VAR` (single node), `$$$` (multiple nodes) - Meta-variables: `$VAR` (single), `$$$` (multiple)
- **Languages**: 25 supported (typescript, tsx, python, rust, go, etc.) - Pattern must be valid AST node, not fragment
- **Binding**: Prefers @ast-grep/napi (native), falls back to @ast-grep/cli - Prefers napi binding for performance
- **Pattern must be valid AST**: `export async function $NAME($$$) { $$$ }` not fragments
## ANTI-PATTERNS (TOOLS) ## ANTI-PATTERNS
- **No timeout**: Always use timeout for file operations (default 60s) - No timeout on file ops (always use, default 60s)
- **Blocking main thread**: Use async/await, never sync file ops - Sync file operations (use async/await)
- **Ignoring LSP errors**: Gracefully handle server not found/crashed - Ignoring LSP errors (graceful handling required)
- **Raw subprocess for ast-grep**: Prefer napi binding for performance - Raw subprocess for ast-grep (prefer napi)