diff --git a/AGENTS.md b/AGENTS.md index 0423ea5..c419669 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,7 +1,7 @@ # PROJECT KNOWLEDGE BASE -**Generated:** 2025-12-22T02:23:00+09:00 -**Commit:** aad7a72 +**Generated:** 2025-12-24T17:07:00+09:00 +**Commit:** 0172241 **Branch:** dev ## OVERVIEW @@ -13,14 +13,14 @@ OpenCode plugin implementing Claude Code/AmpCode features. Multi-model agent orc ``` oh-my-opencode/ ├── src/ -│ ├── agents/ # AI agents (Sisyphus, oracle, librarian, explore, frontend, document-writer, multimodal-looker) -│ ├── hooks/ # 21 lifecycle hooks (comment-checker, rules-injector, keyword-detector, etc.) -│ ├── tools/ # LSP (11), AST-Grep, Grep, Glob, background-task, look-at, skill, slashcommand, interactive-bash, call-omo-agent -│ ├── mcp/ # MCP servers (context7, websearch_exa, grep_app) -│ ├── features/ # Background agent, Claude Code loaders (agent, command, skill, mcp, session-state), hook-message-injector +│ ├── agents/ # AI agents (7): Sisyphus, oracle, librarian, explore, frontend, document-writer, multimodal-looker +│ ├── hooks/ # 21 lifecycle hooks - see src/hooks/AGENTS.md +│ ├── tools/ # LSP, AST-Grep, Grep, Glob, etc. - see src/tools/AGENTS.md +│ ├── mcp/ # MCP servers: context7, websearch_exa, grep_app +│ ├── features/ # Claude Code compatibility - see src/features/AGENTS.md │ ├── config/ # Zod schema, TypeScript types -│ ├── auth/ # Google Antigravity OAuth -│ ├── shared/ # Utilities (deep-merge, pattern-matcher, logger, etc.) +│ ├── auth/ # Google Antigravity OAuth (antigravity/) +│ ├── shared/ # Utilities: deep-merge, pattern-matcher, logger, etc. │ └── index.ts # Main plugin entry (OhMyOpenCodePlugin) ├── script/ # build-schema.ts, publish.ts, generate-changelog.ts ├── assets/ # JSON schema @@ -31,12 +31,12 @@ oh-my-opencode/ | Task | Location | Notes | |------|----------|-------| -| Add new agent | `src/agents/` | Create .ts file, add to builtinAgents in index.ts, update types.ts | -| Add new hook | `src/hooks/` | Create dir with createXXXHook(), export from index.ts | -| Add new tool | `src/tools/` | Dir with index/types/constants/tools.ts, add to builtinTools | -| Add MCP server | `src/mcp/` | Create config, add to index.ts | -| Modify LSP behavior | `src/tools/lsp/` | client.ts for connection, tools.ts for handlers | -| AST-Grep patterns | `src/tools/ast-grep/` | napi.ts for @ast-grep/napi binding | +| Add agent | `src/agents/` | Create .ts, add to builtinAgents in index.ts, update types.ts | +| Add hook | `src/hooks/` | Create dir with createXXXHook(), export from index.ts | +| Add tool | `src/tools/` | Dir with index/types/constants/tools.ts, add to builtinTools | +| Add MCP | `src/mcp/` | Create config, add to index.ts | +| LSP behavior | `src/tools/lsp/` | client.ts (connection), tools.ts (handlers) | +| AST-Grep | `src/tools/ast-grep/` | napi.ts for @ast-grep/napi binding | | Google OAuth | `src/auth/antigravity/` | OAuth plugin for Google 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 | @@ -50,98 +50,72 @@ oh-my-opencode/ - **Build**: Dual output - `bun build` (ESM) + `tsc --emitDeclarationOnly` - **Exports**: Barrel pattern - `export * from "./module"` in index.ts - **Directory naming**: kebab-case (`ast-grep/`, `claude-code-hooks/`) -- **Tool structure**: Each tool has index.ts, types.ts, constants.ts, tools.ts, utils.ts +- **Tool structure**: index.ts, types.ts, constants.ts, tools.ts, utils.ts - **Hook pattern**: `createXXXHook(input: PluginInput)` returning event handlers -- **Test style**: BDD comments `#given`, `#when`, `#then` (same as AAA pattern) +- **Test style**: BDD comments `#given`, `#when`, `#then` (same as AAA) ## ANTI-PATTERNS (THIS PROJECT) - **npm/yarn**: Use bun exclusively - **@types/node**: Use bun-types -- **Bash file operations**: Never use mkdir/touch/rm/cp/mv for file creation in code -- **Generic AI aesthetics**: No Space Grotesk, avoid typical AI-generated UI patterns -- **Direct bun publish**: Use GitHub Actions workflow_dispatch only (OIDC provenance) -- **Local version bump**: Version managed by CI workflow, never modify locally +- **Bash file ops**: Never mkdir/touch/rm/cp/mv for file creation in code +- **Direct bun publish**: GitHub Actions workflow_dispatch only (OIDC provenance) +- **Local version bump**: Version managed by CI workflow +- **Year 2024**: NEVER use 2024 in code/prompts (use current year) - **Rush completion**: Never mark tasks complete without verification -- **Interrupting work**: Complete tasks fully before stopping - **Over-exploration**: Stop searching when sufficient context found ## UNIQUE STYLES -- **Platform handling**: Union type `"darwin" | "linux" | "win32" | "unsupported"` -- **Optional props**: Extensive use of `?` for optional interface properties +- **Platform**: Union type `"darwin" | "linux" | "win32" | "unsupported"` +- **Optional props**: Extensive `?` for optional interface properties - **Flexible objects**: `Record` for dynamic configs -- **Error handling**: Consistent try/catch with async/await in all tools -- **Agent tools restriction**: Use `tools: { include: [...] }` or `tools: { exclude: [...] }` +- **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 naming convention -- **Date references**: NEVER use 2024 in code/prompts (use current year) +- **Hook naming**: `createXXXHook` function convention ## AGENT MODELS | Agent | Model | Purpose | |-------|-------|---------| -| Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator, team leader | -| oracle | openai/gpt-5.2 | Strategic advisor, code review, architecture | -| librarian | anthropic/claude-sonnet-4-5 | Multi-repo analysis, docs lookup, GitHub examples | -| explore | opencode/grok-code | Fast codebase exploration, file patterns | -| frontend-ui-ux-engineer | google/gemini-3-pro-preview | UI generation, design-focused | -| document-writer | google/gemini-3-pro-preview | Technical documentation | -| multimodal-looker | google/gemini-3-flash | PDF/image/diagram analysis | +| Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator | +| oracle | openai/gpt-5.2 | Strategic advisor, code review | +| librarian | anthropic/claude-sonnet-4-5 | Multi-repo analysis, docs | +| explore | opencode/grok-code | Fast codebase exploration | +| frontend-ui-ux-engineer | google/gemini-3-pro-preview | UI generation | +| document-writer | google/gemini-3-pro-preview | Technical docs | +| multimodal-looker | google/gemini-3-flash | PDF/image analysis | ## COMMANDS ```bash -# Type check -bun run typecheck - -# Build (ESM + declarations + schema) -bun run build - -# Clean + Build -bun run rebuild - -# Build schema only -bun run build:schema - -# Run tests -bun test +bun run typecheck # Type check +bun run build # ESM + declarations + schema +bun run rebuild # Clean + Build +bun run build:schema # Schema only +bun test # Run tests ``` ## DEPLOYMENT **GitHub Actions workflow_dispatch only** -1. package.json version NOT modified locally (auto-bumped by workflow) +1. Never modify package.json version locally 2. Commit & push changes -3. Trigger `publish` workflow manually: - - `bump`: major | minor | patch - - `version`: (optional) specific version override +3. Trigger `publish` workflow: `gh workflow run publish -f bump=patch` -```bash -# Trigger via CLI -gh workflow run publish -f bump=patch - -# Check status -gh run list --workflow=publish -``` - -**Critical**: -- Never run `bun publish` directly (OIDC provenance issue) -- Never bump version locally +**Critical**: Never `bun publish` directly. Never bump version locally. ## CI PIPELINE -- **ci.yml**: Parallel test/typecheck jobs, build verification, auto-commit schema changes on master -- **publish.yml**: Manual workflow_dispatch, version bump, changelog generation, OIDC npm publishing -- Schema auto-commit prevents build drift -- Draft release creation on dev branch +- **ci.yml**: Parallel test/typecheck, build verification, auto-commit schema on master +- **publish.yml**: Manual workflow_dispatch, version bump, changelog, OIDC npm publish ## NOTES -- **Testing**: Bun native test framework (`bun test`), BDD-style with `#given/#when/#then` comments -- **OpenCode version**: Requires >= 1.0.150 (earlier versions have config bugs) -- **Multi-language docs**: README.md (EN), README.ko.md (KO), README.ja.md (JA), README.zh-cn.md (ZH-CN) -- **Config locations**: `~/.config/opencode/oh-my-opencode.json` (user) or `.opencode/oh-my-opencode.json` (project) -- **Schema autocomplete**: Add `$schema` field in config for IDE support -- **Trusted dependencies**: @ast-grep/cli, @ast-grep/napi, @code-yeongyu/comment-checker +- **Testing**: Bun native test (`bun test`), BDD-style `#given/#when/#then` +- **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` (user) or `.opencode/oh-my-opencode.json` (project) +- **Trusted deps**: @ast-grep/cli, @ast-grep/napi, @code-yeongyu/comment-checker diff --git a/src/features/AGENTS.md b/src/features/AGENTS.md new file mode 100644 index 0000000..0a8d8f7 --- /dev/null +++ b/src/features/AGENTS.md @@ -0,0 +1,78 @@ +# FEATURES KNOWLEDGE BASE + +## OVERVIEW + +Claude Code compatibility layer and core feature modules. Enables Claude Code configs/commands/skills/MCPs/hooks to work seamlessly in OpenCode. + +## STRUCTURE + +``` +features/ +├── background-agent/ # Background task management +│ ├── manager.ts # Task lifecycle, notifications +│ ├── manager.test.ts +│ └── types.ts +├── 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 +├── claude-code-session-state/ # Session state persistence +├── claude-code-skill-loader/ # Load skills from ~/.claude/skills/*/SKILL.md +└── hook-message-injector/ # Inject messages into conversation +``` + +## LOADER PRIORITY + +Each loader reads from multiple directories (highest priority first): + +| Loader | Priority Order | +|--------|---------------| +| Commands | `.opencode/command/` > `~/.config/opencode/command/` > `.claude/commands/` > `~/.claude/commands/` | +| Skills | `.claude/skills/` > `~/.claude/skills/` | +| Agents | `.claude/agents/` > `~/.claude/agents/` | +| 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 + +Disable features in `oh-my-opencode.json`: + +```json +{ + "claude_code": { + "mcp": false, // Skip .mcp.json loading + "commands": false, // Skip commands/*.md loading + "skills": false, // Skip skills/*/SKILL.md loading + "agents": false, // Skip agents/*.md loading + "hooks": false // Skip settings.json hooks + } +} +``` + +## HOOK MESSAGE INJECTOR + +- **Purpose**: Inject system messages into conversation at specific points +- **Timing**: PreToolUse, PostToolUse, UserPromptSubmit, Stop +- **Format**: Returns `{ messages: [{ role: "user", content: "..." }] }` + +## 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/ diff --git a/src/hooks/AGENTS.md b/src/hooks/AGENTS.md new file mode 100644 index 0000000..36abe0f --- /dev/null +++ b/src/hooks/AGENTS.md @@ -0,0 +1,83 @@ +# HOOKS KNOWLEDGE BASE + +## OVERVIEW + +Lifecycle hooks that intercept/modify agent behavior. Inject context, enforce rules, recover from errors, notify on events. + +## STRUCTURE + +``` +hooks/ +├── agent-usage-reminder/ # Remind to use specialized agents +├── anthropic-auto-compact/ # Auto-compact Claude at token limit +├── auto-update-checker/ # Version update notifications +├── background-notification/ # OS notify on background task complete +├── claude-code-hooks/ # Claude Code settings.json integration +├── comment-checker/ # Prevent excessive AI comments +│ ├── filters/ # Filtering rules (docstring, directive, bdd, etc.) +│ └── output/ # Output formatting +├── compaction-context-injector/ # Inject context during compaction +├── directory-agents-injector/ # Auto-inject AGENTS.md files +├── directory-readme-injector/ # Auto-inject README.md files +├── empty-message-sanitizer/ # Sanitize empty messages +├── interactive-bash-session/ # Tmux session management +├── keyword-detector/ # Detect ultrawork/search keywords +├── non-interactive-env/ # CI/headless environment handling +├── preemptive-compaction/ # Pre-emptive session compaction +├── rules-injector/ # Conditional rules from .claude/rules/ +├── session-recovery/ # Recover from session errors +├── think-mode/ # Auto-detect thinking triggers +├── context-window-monitor.ts # Monitor context usage (standalone) +├── empty-task-response-detector.ts +├── session-notification.ts # OS notify on idle (standalone) +├── todo-continuation-enforcer.ts # Force TODO completion (standalone) +└── 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-auto-compact, 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 + +| Event | Timing | Can Block | Use Case | +|-------|--------|-----------|----------| +| PreToolUse | Before tool exec | Yes | Validate, modify input | +| PostToolUse | After tool exec | No | Add context, warnings | +| UserPromptSubmit | On user prompt | Yes | Inject messages, block | +| Stop | Session idle | No | Inject follow-ups | +| onSummarize | During compaction | No | Preserve critical context | + +## COMMON PATTERNS + +- **Storage**: Use `storage.ts` with JSON file for persistent state across sessions +- **Once-per-session**: Track injected paths in Set to avoid duplicate injection +- **Message injection**: Return `{ messages: [...] }` from event handlers +- **Blocking**: Return `{ blocked: true, message: "reason" }` from PreToolUse + +## ANTI-PATTERNS (HOOKS) + +- **Heavy computation** in PreToolUse: Slows every tool call +- **Blocking without clear reason**: Always provide actionable message +- **Duplicate injection**: Track what's already injected per session +- **Ignoring errors**: Always try/catch, log failures, don't crash session diff --git a/src/tools/AGENTS.md b/src/tools/AGENTS.md new file mode 100644 index 0000000..8d19041 --- /dev/null +++ b/src/tools/AGENTS.md @@ -0,0 +1,73 @@ +# TOOLS KNOWLEDGE BASE + +## OVERVIEW + +Custom tools extending agent capabilities: LSP integration (11 tools), AST-aware code search/replace, file operations with timeouts, background task management. + +## STRUCTURE + +``` +tools/ +├── ast-grep/ # AST-aware code search/replace (25 languages) +│ ├── cli.ts # @ast-grep/cli subprocess +│ ├── napi.ts # @ast-grep/napi native binding (preferred) +│ ├── constants.ts, types.ts, tools.ts, utils.ts +├── background-task/ # Async agent task management +├── call-omo-agent/ # Spawn explore/librarian agents +├── glob/ # File pattern matching (timeout-safe) +├── grep/ # Content search (timeout-safe) +├── interactive-bash/ # Tmux session management +├── look-at/ # Multimodal analysis (PDF, images) +├── lsp/ # 11 LSP tools +│ ├── client.ts # LSP connection lifecycle +│ ├── config.ts # Server configurations +│ ├── tools.ts # Tool implementations +│ └── types.ts +├── slashcommand/ # Slash command execution +└── index.ts # builtinTools export +``` + +## TOOL CATEGORIES + +| Category | Tools | Purpose | +|----------|-------|---------| +| 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 | +| AST | ast_grep_search, ast_grep_replace | Pattern-based code search/replace | +| File Search | grep, glob | Content and file pattern matching | +| Background | background_task, background_output, background_cancel | Async agent orchestration | +| Multimodal | look_at | PDF/image analysis via Gemini | +| Terminal | interactive_bash | Tmux session control | +| Commands | slashcommand | Execute slash commands | +| Agents | call_omo_agent | Spawn explore/librarian | + +## HOW TO ADD A TOOL + +1. Create directory: `src/tools/my-tool/` +2. Create files: + - `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` + +## LSP SPECIFICS + +- **Client lifecycle**: Lazy init on first use, auto-shutdown on idle +- **Config priority**: opencode.json > oh-my-opencode.json > defaults +- **Supported servers**: typescript-language-server, pylsp, gopls, rust-analyzer, etc. +- **Custom servers**: Add via `lsp` config in oh-my-opencode.json + +## AST-GREP SPECIFICS + +- **Meta-variables**: `$VAR` (single node), `$$$` (multiple nodes) +- **Languages**: 25 supported (typescript, tsx, python, rust, go, etc.) +- **Binding**: Prefers @ast-grep/napi (native), falls back to @ast-grep/cli +- **Pattern must be valid AST**: `export async function $NAME($$$) { $$$ }` not fragments + +## ANTI-PATTERNS (TOOLS) + +- **No timeout**: Always use timeout for file operations (default 60s) +- **Blocking main thread**: Use async/await, never sync file ops +- **Ignoring LSP errors**: Gracefully handle server not found/crashed +- **Raw subprocess for ast-grep**: Prefer napi binding for performance