diff --git a/AGENTS.md b/AGENTS.md index 2c12d29a4..aa6212805 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,28 +1,28 @@ # PROJECT KNOWLEDGE BASE -**Generated:** 2026-01-22T22:25:00+09:00 -**Commit:** 85bf266f +**Generated:** 2026-01-23T02:09:00+09:00 +**Commit:** 0e18efc7 **Branch:** dev ## OVERVIEW -OpenCode plugin implementing multi-model agent orchestration (Claude Opus 4.5, GPT-5.2, Gemini 3, Grok, GLM-4.7). 31 lifecycle hooks, 20+ tools (LSP, AST-Grep, delegation), 10 specialized agents, Claude Code compatibility layer. "oh-my-zsh" for OpenCode. +OpenCode plugin: multi-model agent orchestration (Claude Opus 4.5, GPT-5.2, Gemini 3, Grok, GLM-4.7). 31 lifecycle hooks, 20+ tools (LSP, AST-Grep, delegation), 10 specialized agents, full Claude Code compatibility. "oh-my-zsh" for OpenCode. ## STRUCTURE ``` oh-my-opencode/ ├── src/ -│ ├── agents/ # 10 AI agents (Sisyphus, oracle, librarian, explore, etc.) - see src/agents/AGENTS.md -│ ├── hooks/ # 31 lifecycle hooks (PreToolUse, PostToolUse, Stop, etc.) - see src/hooks/AGENTS.md -│ ├── tools/ # 20+ tools (LSP, AST-Grep, delegation, session) - see src/tools/AGENTS.md -│ ├── features/ # Background agents, Claude Code compat layer - see src/features/AGENTS.md +│ ├── agents/ # 10 AI agents - see src/agents/AGENTS.md +│ ├── hooks/ # 31 lifecycle hooks - see src/hooks/AGENTS.md +│ ├── tools/ # 20+ tools - see src/tools/AGENTS.md +│ ├── features/ # Background agents, Claude Code compat - see src/features/AGENTS.md │ ├── shared/ # 50 cross-cutting utilities - see src/shared/AGENTS.md -│ ├── cli/ # CLI installer, doctor, run - see src/cli/AGENTS.md -│ ├── mcp/ # Built-in MCPs: websearch, context7, grep_app - see src/mcp/AGENTS.md +│ ├── cli/ # CLI installer, doctor - see src/cli/AGENTS.md +│ ├── mcp/ # Built-in MCPs - see src/mcp/AGENTS.md │ ├── config/ # Zod schema, TypeScript types -│ └── index.ts # Main plugin entry (589 lines) -├── script/ # build-schema.ts, publish.ts, build-binaries.ts +│ └── index.ts # Main plugin entry (590 lines) +├── script/ # build-schema.ts, build-binaries.ts ├── packages/ # 7 platform-specific binaries └── dist/ # Build output (ESM + .d.ts) ``` @@ -31,88 +31,67 @@ oh-my-opencode/ | Task | Location | Notes | |------|----------|-------| -| Add agent | `src/agents/` | Create .ts with factory, add to `builtinAgents` in index.ts | +| Add agent | `src/agents/` | Create .ts with factory, add to `agentSources` | | Add hook | `src/hooks/` | Create dir with `createXXXHook()`, register in index.ts | -| Add tool | `src/tools/` | Dir with index/types/constants/tools.ts, add to `builtinTools` | +| Add tool | `src/tools/` | Dir with index/types/constants/tools.ts | | Add MCP | `src/mcp/` | Create config, add to index.ts | | Add skill | `src/features/builtin-skills/` | Create dir with SKILL.md | -| LSP behavior | `src/tools/lsp/` | client.ts (connection), tools.ts (handlers) | -| AST-Grep | `src/tools/ast-grep/` | napi.ts for @ast-grep/napi binding | -| 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 | -| Background agents | `src/features/background-agent/` | manager.ts (1335 lines) for task lifecycle | -| Skill MCP | `src/features/skill-mcp-manager/` | MCP servers embedded in skills | -| CLI installer | `src/cli/install.ts` | Interactive TUI (520 lines) | -| Doctor checks | `src/cli/doctor/checks/` | 14 health checks across 6 categories | -| Orchestrator hook | `src/hooks/atlas/` | Main orchestration hook (771 lines) | +| Config schema | `src/config/schema.ts` | Zod schema, run `bun run build:schema` | +| Background agents | `src/features/background-agent/` | manager.ts (1335 lines) | +| Orchestrator | `src/hooks/atlas/` | Main orchestration hook (771 lines) | ## TDD (Test-Driven Development) -**MANDATORY for new features and bug fixes.** Follow RED-GREEN-REFACTOR: - -| Phase | Action | Verification | -|-------|--------|--------------| -| **RED** | Write test describing expected behavior | `bun test` → FAIL (expected) | -| **GREEN** | Implement minimum code to pass | `bun test` → PASS | -| **REFACTOR** | Improve code quality, remove duplication | `bun test` → PASS (must stay green) | +**MANDATORY.** RED-GREEN-REFACTOR: +1. **RED**: Write test → `bun test` → FAIL +2. **GREEN**: Implement minimum → PASS +3. **REFACTOR**: Clean up → stay GREEN **Rules:** - NEVER write implementation before test -- NEVER delete failing tests to "pass" - fix the code -- Test file naming: `*.test.ts` alongside source -- BDD comments: `#given`, `#when`, `#then` (same as AAA) +- NEVER delete failing tests - fix the code +- Test file: `*.test.ts` alongside source +- BDD comments: `#given`, `#when`, `#then` ## CONVENTIONS - **Package manager**: Bun only (`bun run`, `bun build`, `bunx`) -- **Types**: bun-types (not @types/node) +- **Types**: bun-types (NEVER @types/node) - **Build**: `bun build` (ESM) + `tsc --emitDeclarationOnly` -- **Exports**: Barrel pattern in index.ts; explicit named exports -- **Naming**: kebab-case directories, `createXXXHook`/`createXXXTool` factories -- **Testing**: BDD comments `#given/#when/#then`, 83 test files +- **Exports**: Barrel pattern via index.ts +- **Naming**: kebab-case dirs, `createXXXHook`/`createXXXTool` factories +- **Testing**: BDD comments, 90 test files - **Temperature**: 0.1 for code agents, max 0.3 -## ANTI-PATTERNS (THIS PROJECT) +## ANTI-PATTERNS | Category | Forbidden | |----------|-----------| -| **Package Manager** | npm, yarn - use Bun exclusively | -| **Types** | @types/node - use bun-types | -| **File Ops** | mkdir/touch/rm/cp/mv in code - agents use bash tool | -| **Publishing** | Direct `bun publish` - use GitHub Actions workflow_dispatch | -| **Versioning** | Local version bump - managed by CI | -| **Date References** | Year 2024 - use current year | -| **Type Safety** | `as any`, `@ts-ignore`, `@ts-expect-error` | -| **Error Handling** | Empty catch blocks `catch(e) {}` | -| **Testing** | Deleting failing tests to "pass" | -| **Agent Calls** | Sequential agent calls - use `delegate_task` for parallel | -| **Tool Access** | Broad tool access - prefer explicit `include` | -| **Hook Logic** | Heavy PreToolUse computation - slows every tool call | -| **Commits** | Giant commits (3+ files = 2+ commits), separate test from impl | -| **Temperature** | >0.3 for code agents | -| **Trust** | Trust agent self-reports - ALWAYS verify independently | - -## UNIQUE STYLES - -- **Platform**: Union type `"darwin" | "linux" | "win32" | "unsupported"` -- **Optional props**: Extensive `?` for optional interface properties -- **Flexible objects**: `Record` for dynamic configs -- **Agent tools**: `tools: { include: [...] }` or `tools: { exclude: [...] }` -- **Hook naming**: `createXXXHook` function convention -- **Factory pattern**: Components created via `createXXX()` functions +| Package Manager | npm, yarn - Bun exclusively | +| Types | @types/node - use bun-types | +| File Ops | mkdir/touch/rm/cp/mv in code - use bash tool | +| Publishing | Direct `bun publish` - GitHub Actions only | +| Versioning | Local version bump - CI manages | +| Type Safety | `as any`, `@ts-ignore`, `@ts-expect-error` | +| Error Handling | Empty catch blocks | +| Testing | Deleting failing tests | +| Agent Calls | Sequential - use `delegate_task` parallel | +| Hook Logic | Heavy PreToolUse - slows every call | +| Commits | Giant (3+ files), separate test from impl | +| Temperature | >0.3 for code agents | +| Trust | Agent self-reports - ALWAYS verify | ## AGENT MODELS -| Agent | Default Model | Purpose | -|-------|---------------|---------| -| Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator with extended thinking | -| oracle | openai/gpt-5.2 | Read-only consultation, high-IQ debugging | -| librarian | opencode/glm-4.7-free | Multi-repo analysis, docs, GitHub search | -| explore | opencode/grok-code | Fast codebase exploration (contextual grep) | +| Agent | Model | Purpose | +|-------|-------|---------| +| Sisyphus | anthropic/claude-opus-4-5 | Primary orchestrator | +| Atlas | anthropic/claude-opus-4-5 | Master orchestrator | +| oracle | openai/gpt-5.2 | Consultation, debugging | +| librarian | opencode/glm-4.7-free | Docs, GitHub search | +| explore | opencode/grok-code | Fast codebase grep | | multimodal-looker | google/gemini-3-flash | PDF/image analysis | -| Prometheus (Planner) | anthropic/claude-opus-4-5 | Strategic planning, interview mode | -| Metis (Plan Consultant) | anthropic/claude-sonnet-4-5 | Pre-planning analysis | -| Momus (Plan Reviewer) | anthropic/claude-sonnet-4-5 | Plan validation | +| Prometheus | anthropic/claude-opus-4-5 | Strategic planning | ## COMMANDS @@ -120,60 +99,42 @@ oh-my-opencode/ 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 (83 test files) +bun test # 90 test files ``` ## DEPLOYMENT -**GitHub Actions workflow_dispatch only** - -1. Never modify package.json version locally -2. Commit & push changes -3. Trigger `publish` workflow: `gh workflow run publish -f bump=patch` - -**Critical**: Never `bun publish` directly. Never bump version locally. - -## CI PIPELINE - -- **ci.yml**: Parallel test/typecheck → build → auto-commit schema on master → rolling `next` draft release -- **publish.yml**: Manual workflow_dispatch → version bump → changelog → 8-package OIDC npm publish → force-push master +**GitHub Actions workflow_dispatch ONLY** +1. Commit & push changes +2. Trigger: `gh workflow run publish -f bump=patch` +3. Never `bun publish` directly, never bump version locally ## COMPLEXITY HOTSPOTS | File | Lines | Description | |------|-------|-------------| -| `src/agents/atlas.ts` | 1383 | Orchestrator agent, 7-section delegation, wisdom accumulation | -| `src/features/background-agent/manager.ts` | 1335 | Task lifecycle, concurrency, notification batching | -| `src/features/builtin-skills/skills.ts` | 1203 | Skill definitions (playwright, git-master, frontend-ui-ux) | -| `src/agents/prometheus-prompt.ts` | 1196 | Planning agent, interview mode, Momus loop | -| `src/tools/delegate-task/tools.ts` | 1027 | Category-based task delegation | -| `src/hooks/atlas/index.ts` | 771 | Orchestrator hook implementation | -| `src/cli/config-manager.ts` | 641 | JSONC parsing, multi-level config | -| `src/features/builtin-commands/templates/refactor.ts` | 619 | Refactoring command template | -| `src/agents/sisyphus.ts` | 615 | Main Sisyphus prompt | -| `src/tools/lsp/client.ts` | 596 | LSP protocol, JSON-RPC | +| `src/agents/atlas.ts` | 1383 | Orchestrator, 7-section delegation | +| `src/features/background-agent/manager.ts` | 1335 | Task lifecycle, concurrency | +| `src/features/builtin-skills/skills.ts` | 1203 | Skill definitions | +| `src/agents/prometheus-prompt.ts` | 1196 | Planning agent | +| `src/tools/delegate-task/tools.ts` | 1038 | Category-based delegation | +| `src/hooks/atlas/index.ts` | 771 | Orchestrator hook | ## MCP ARCHITECTURE -Three-tier MCP system: -1. **Built-in**: `websearch` (Exa), `context7` (docs), `grep_app` (GitHub search) -2. **Claude Code compatible**: `.mcp.json` files with `${VAR}` expansion -3. **Skill-embedded**: YAML frontmatter in skills (e.g., playwright) +Three-tier system: +1. **Built-in**: websearch (Exa), context7 (docs), grep_app (GitHub) +2. **Claude Code compat**: .mcp.json with `${VAR}` expansion +3. **Skill-embedded**: YAML frontmatter in skills ## CONFIG SYSTEM - **Zod validation**: `src/config/schema.ts` -- **JSONC support**: Comments and trailing commas +- **JSONC support**: Comments, trailing commas - **Multi-level**: Project (`.opencode/`) → User (`~/.config/opencode/`) -- **CLI doctor**: Validates config and reports errors ## NOTES -- **Testing**: Bun native test (`bun test`), BDD-style, 83 test files - **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) +- **Flaky tests**: ralph-loop (CI timeout), session-state (parallel pollution) - **Trusted deps**: @ast-grep/cli, @ast-grep/napi, @code-yeongyu/comment-checker -- **Claude Code Compat**: Full compatibility layer for settings.json hooks, commands, skills, agents, MCPs -- **Flaky tests**: 2 known flaky tests (ralph-loop CI timeout, session-state parallel pollution) diff --git a/src/agents/AGENTS.md b/src/agents/AGENTS.md index 2d86b9497..5b1a85484 100644 --- a/src/agents/AGENTS.md +++ b/src/agents/AGENTS.md @@ -8,17 +8,17 @@ ``` agents/ -├── atlas.ts # Master Orchestrator (1383 lines) - 7-phase delegation +├── atlas.ts # Master Orchestrator (1383 lines) ├── sisyphus.ts # Main prompt (615 lines) -├── sisyphus-junior.ts # Delegated task executor (136 lines) -├── dynamic-agent-prompt-builder.ts # Dynamic prompt generation (360 lines) +├── sisyphus-junior.ts # Delegated task executor +├── dynamic-agent-prompt-builder.ts # Dynamic prompt generation ├── oracle.ts # Strategic advisor (GPT-5.2) ├── librarian.ts # Multi-repo research (GLM-4.7-free) ├── explore.ts # Fast grep (Grok Code) ├── multimodal-looker.ts # Media analyzer (Gemini 3 Flash) -├── prometheus-prompt.ts # Planning (1196 lines) - interview mode -├── metis.ts # Plan consultant - pre-planning analysis -├── momus.ts # Plan reviewer - validation +├── prometheus-prompt.ts # Planning (1196 lines) +├── metis.ts # Plan consultant +├── momus.ts # Plan reviewer ├── types.ts # AgentModelConfig, AgentPromptMetadata ├── utils.ts # createBuiltinAgents(), resolveModelWithFallback() └── index.ts # builtinAgents export @@ -26,16 +26,16 @@ agents/ ## AGENT MODELS -| Agent | Model | Temperature | Purpose | -|-------|-------|-------------|---------| -| Sisyphus | anthropic/claude-opus-4-5 | 0.1 | Primary orchestrator, todo-driven | -| Atlas | anthropic/claude-opus-4-5 | 0.1 | Master orchestrator, delegate_task | -| oracle | openai/gpt-5.2 | 0.1 | Read-only consultation, debugging | -| librarian | opencode/glm-4.7-free | 0.1 | Docs, GitHub search, OSS examples | +| Agent | Model | Temp | Purpose | +|-------|-------|------|---------| +| Sisyphus | anthropic/claude-opus-4-5 | 0.1 | Primary orchestrator | +| Atlas | anthropic/claude-opus-4-5 | 0.1 | Master orchestrator | +| oracle | openai/gpt-5.2 | 0.1 | Consultation, debugging | +| librarian | opencode/glm-4.7-free | 0.1 | Docs, GitHub search | | explore | opencode/grok-code | 0.1 | Fast contextual grep | | multimodal-looker | google/gemini-3-flash | 0.1 | PDF/image analysis | -| Prometheus | anthropic/claude-opus-4-5 | 0.1 | Strategic planning, interview mode | -| Metis | anthropic/claude-sonnet-4-5 | 0.3 | Pre-planning gap analysis | +| Prometheus | anthropic/claude-opus-4-5 | 0.1 | Strategic planning | +| Metis | anthropic/claude-sonnet-4-5 | 0.3 | Pre-planning analysis | | Momus | anthropic/claude-sonnet-4-5 | 0.1 | Plan validation | | Sisyphus-Junior | anthropic/claude-sonnet-4-5 | 0.1 | Category-spawned executor | @@ -54,19 +54,17 @@ agents/ | librarian | write, edit, task, delegate_task, call_omo_agent | | explore | write, edit, task, delegate_task, call_omo_agent | | multimodal-looker | Allowlist: read only | -| Sisyphus-Junior | task, delegate_task (cannot spawn implementation agents) | +| Sisyphus-Junior | task, delegate_task | -## KEY PATTERNS +## PATTERNS - **Factory**: `createXXXAgent(model?: string): AgentConfig` -- **Metadata**: `XXX_PROMPT_METADATA: AgentPromptMetadata` with category, cost, triggers +- **Metadata**: `XXX_PROMPT_METADATA` with category, cost, triggers - **Tool restrictions**: `createAgentToolRestrictions(tools)` or `createAgentToolAllowlist(tools)` - **Thinking**: 32k budget tokens for Sisyphus, Oracle, Prometheus, Atlas -- **Model-specific**: GPT uses `reasoningEffort`, Anthropic uses `thinking` budget ## ANTI-PATTERNS -- **Trust reports**: NEVER trust subagent "I'm done" - verify outputs +- **Trust reports**: NEVER trust "I'm done" - verify outputs - **High temp**: Don't use >0.3 for code agents - **Sequential calls**: Use `delegate_task` with `run_in_background` -- **Missing metadata**: Every agent needs `XXX_PROMPT_METADATA` export diff --git a/src/cli/AGENTS.md b/src/cli/AGENTS.md index 7a63a1c2d..97ff376d2 100644 --- a/src/cli/AGENTS.md +++ b/src/cli/AGENTS.md @@ -2,90 +2,70 @@ ## OVERVIEW -CLI entry point: `bunx oh-my-opencode`. Interactive installer, doctor diagnostics, session runner. Uses Commander.js + @clack/prompts TUI. +CLI entry: `bunx oh-my-opencode`. Interactive installer, doctor diagnostics. Commander.js + @clack/prompts. ## STRUCTURE ``` cli/ -├── index.ts # Commander.js entry, 5 subcommands -├── install.ts # Interactive TUI installer (520 lines) -├── config-manager.ts # JSONC parsing, multi-level merge (641 lines) -├── types.ts # InstallArgs, InstallConfig, DetectedConfig +├── index.ts # Commander.js entry +├── install.ts # Interactive TUI (520 lines) +├── config-manager.ts # JSONC parsing (641 lines) +├── types.ts # InstallArgs, InstallConfig ├── doctor/ -│ ├── index.ts # Doctor command entry +│ ├── index.ts # Doctor entry │ ├── runner.ts # Check orchestration -│ ├── formatter.ts # Colored output, symbols -│ ├── constants.ts # Check IDs, categories, symbols +│ ├── formatter.ts # Colored output +│ ├── constants.ts # Check IDs, symbols │ ├── types.ts # CheckResult, CheckDefinition -│ └── checks/ # 14 checks across 6 categories (21 files) +│ └── checks/ # 14 checks, 21 files │ ├── version.ts # OpenCode + plugin version -│ ├── config.ts # JSONC validity, Zod validation +│ ├── config.ts # JSONC validity, Zod │ ├── auth.ts # Anthropic, OpenAI, Google │ ├── dependencies.ts # AST-Grep, Comment Checker -│ ├── lsp.ts # LSP server connectivity -│ ├── mcp.ts # MCP server validation -│ └── gh.ts # GitHub CLI availability +│ ├── lsp.ts # LSP connectivity +│ ├── mcp.ts # MCP validation +│ └── gh.ts # GitHub CLI ├── run/ -│ ├── index.ts # Run command entry -│ └── runner.ts # Session launcher +│ └── index.ts # Session launcher └── get-local-version/ - ├── index.ts # Version detection - └── formatter.ts # Version output + └── index.ts # Version detection ``` -## CLI COMMANDS +## COMMANDS | Command | Purpose | |---------|---------| -| `install` | Interactive setup, subscription detection | -| `doctor` | 14 health checks, `--verbose`, `--json`, `--category` | -| `run` | Launch OpenCode session with completion enforcement | -| `get-local-version` | Version detection, update checking | +| `install` | Interactive setup | +| `doctor` | 14 health checks | +| `run` | Launch session | +| `get-local-version` | Version check | -## DOCTOR CHECK CATEGORIES +## DOCTOR CATEGORIES | Category | Checks | |----------|--------| -| installation | opencode, plugin registration | -| configuration | config validity, Zod validation | +| installation | opencode, plugin | +| configuration | config validity, Zod | | authentication | anthropic, openai, google | -| dependencies | ast-grep CLI/NAPI, comment-checker | -| tools | LSP, MCP connectivity | +| dependencies | ast-grep, comment-checker | +| tools | LSP, MCP | | updates | version comparison | ## HOW TO ADD CHECK -1. Create `src/cli/doctor/checks/my-check.ts`: - ```typescript - export function getMyCheckDefinition(): CheckDefinition { - return { - id: "my-check", - name: "My Check", - category: "configuration", - check: async () => ({ status: "pass", message: "OK" }) - } - } - ``` +1. Create `src/cli/doctor/checks/my-check.ts` 2. Export from `checks/index.ts` 3. Add to `getAllCheckDefinitions()` ## TUI FRAMEWORK -- **@clack/prompts**: `select()`, `spinner()`, `intro()`, `outro()`, `note()` -- **picocolors**: Colored terminal output -- **Symbols**: ✓ (pass), ✗ (fail), ⚠ (warn), ○ (skip) - -## CONFIG-MANAGER - -- **JSONC**: Comments (`// ...`), block comments, trailing commas -- **Multi-source**: User (`~/.config/opencode/`) + Project (`.opencode/`) -- **Env override**: `OPENCODE_CONFIG_DIR` for profile isolation -- **Validation**: Zod schema with error aggregation +- **@clack/prompts**: `select()`, `spinner()`, `intro()` +- **picocolors**: Terminal colors +- **Symbols**: ✓ (pass), ✗ (fail), ⚠ (warn) ## ANTI-PATTERNS - **Blocking in non-TTY**: Check `process.stdout.isTTY` -- **Direct JSON.parse**: Use `parseJsonc()` for config -- **Silent failures**: Always return warn/fail in doctor -- **Hardcoded paths**: Use `ConfigManager` +- **Direct JSON.parse**: Use `parseJsonc()` +- **Silent failures**: Return warn/fail in doctor diff --git a/src/features/AGENTS.md b/src/features/AGENTS.md index 65581add6..4b92bbc83 100644 --- a/src/features/AGENTS.md +++ b/src/features/AGENTS.md @@ -2,32 +2,30 @@ ## OVERVIEW -Core feature modules + Claude Code compatibility layer. Background agents, skill MCP, builtin skills/commands, and 5 loaders for Claude Code compat. +Core feature modules + Claude Code compatibility layer. Background agents, skill MCP, builtin skills/commands, 5 loaders. ## STRUCTURE ``` features/ -├── background-agent/ # Task lifecycle (1335 lines manager.ts) -│ ├── manager.ts # Launch → poll → complete orchestration -│ ├── concurrency.ts # Per-provider/model limits +├── background-agent/ # Task lifecycle (1335 lines) +│ ├── manager.ts # Launch → poll → complete +│ ├── concurrency.ts # Per-provider limits │ └── types.ts # BackgroundTask, LaunchInput -├── skill-mcp-manager/ # MCP client lifecycle (520 lines) -│ ├── manager.ts # Lazy loading, idle cleanup -│ └── types.ts # SkillMcpConfig, transports +├── skill-mcp-manager/ # MCP client lifecycle +│ ├── manager.ts # Lazy loading, cleanup +│ └── types.ts # SkillMcpConfig ├── builtin-skills/ # Playwright, git-master, frontend-ui-ux -│ └── skills.ts # 1203 lines of skill definitions +│ └── skills.ts # 1203 lines ├── builtin-commands/ # ralph-loop, refactor, init-deep -│ └── templates/ # Command implementations ├── claude-code-agent-loader/ # ~/.claude/agents/*.md ├── claude-code-command-loader/ # ~/.claude/commands/*.md -├── claude-code-mcp-loader/ # .mcp.json with ${VAR} expansion +├── claude-code-mcp-loader/ # .mcp.json ├── claude-code-plugin-loader/ # installed_plugins.json -├── claude-code-session-state/ # Session state persistence -├── opencode-skill-loader/ # Skills from 6 directories (12 files) +├── claude-code-session-state/ # Session persistence +├── opencode-skill-loader/ # Skills from 6 directories ├── context-injector/ # AGENTS.md/README.md injection ├── boulder-state/ # Todo state persistence -├── task-toast-manager/ # Toast notifications └── hook-message-injector/ # Message injection ``` @@ -35,43 +33,25 @@ features/ | Type | Priority (highest first) | |------|--------------------------| -| Commands | `.opencode/command/` > `~/.config/opencode/command/` > `.claude/commands/` > `~/.claude/commands/` | -| Skills | `.opencode/skills/` > `~/.config/opencode/skills/` > `.claude/skills/` > `~/.claude/skills/` | -| Agents | `.claude/agents/` > `~/.claude/agents/` | +| Commands | `.opencode/command/` > `~/.config/opencode/command/` > `.claude/commands/` | +| Skills | `.opencode/skills/` > `~/.config/opencode/skills/` > `.claude/skills/` | | MCPs | `.claude/.mcp.json` > `.mcp.json` > `~/.claude/.mcp.json` | ## BACKGROUND AGENT -- **Lifecycle**: `launch` → `poll` (2s interval) → `complete` -- **Stability**: 3 consecutive polls with same message count = idle -- **Concurrency**: Per-provider/model limits (e.g., max 3 Opus, max 10 Gemini) -- **Notification**: Batched system reminders to parent session -- **Cleanup**: 30m TTL, 3m stale timeout, signal handlers +- **Lifecycle**: `launch` → `poll` (2s) → `complete` +- **Stability**: 3 consecutive polls = idle +- **Concurrency**: Per-provider/model limits +- **Cleanup**: 30m TTL, 3m stale timeout ## SKILL MCP -- **Lazy**: Clients created on first tool call -- **Transports**: stdio (local process), http (SSE/Streamable) -- **Environment**: `${VAR}` expansion in config -- **Lifecycle**: 5m idle cleanup, session-scoped - -## CONFIG TOGGLES - -```jsonc -{ - "claude_code": { - "mcp": false, // Skip .mcp.json - "commands": false, // Skip commands/*.md - "skills": false, // Skip skills/*/SKILL.md - "agents": false, // Skip agents/*.md - "hooks": false // Skip settings.json hooks - } -} -``` +- **Lazy**: Clients created on first call +- **Transports**: stdio, http (SSE/Streamable) +- **Lifecycle**: 5m idle cleanup ## ANTI-PATTERNS -- **Sequential delegation**: Use `delegate_task` for parallel -- **Trust self-reports**: ALWAYS verify agent outputs +- **Sequential delegation**: Use `delegate_task` parallel +- **Trust self-reports**: ALWAYS verify - **Main thread blocks**: No heavy I/O in loader init -- **Manual versioning**: CI manages package.json version diff --git a/src/hooks/AGENTS.md b/src/hooks/AGENTS.md index 9b402efd3..b5322e6c0 100644 --- a/src/hooks/AGENTS.md +++ b/src/hooks/AGENTS.md @@ -8,27 +8,26 @@ ``` hooks/ -├── atlas/ # Main orchestration & delegation (771 lines) -├── anthropic-context-window-limit-recovery/ # Auto-summarize at token limit +├── atlas/ # Main orchestration (771 lines) +├── anthropic-context-window-limit-recovery/ # Auto-summarize ├── todo-continuation-enforcer.ts # Force TODO completion -├── ralph-loop/ # Self-referential dev loop until done -├── claude-code-hooks/ # settings.json hook compat layer (14 files) - see AGENTS.md -├── comment-checker/ # Prevents AI slop/excessive comments +├── ralph-loop/ # Self-referential dev loop +├── claude-code-hooks/ # settings.json compat layer - see AGENTS.md +├── comment-checker/ # Prevents AI slop ├── auto-slash-command/ # Detects /command patterns -├── rules-injector/ # Conditional rules from .claude/rules/ -├── directory-agents-injector/ # Auto-injects AGENTS.md files -├── directory-readme-injector/ # Auto-injects README.md files -├── preemptive-compaction/ # Triggers summary at 85% context -├── edit-error-recovery/ # Recovers from tool failures -├── thinking-block-validator/ # Ensures valid format -├── context-window-monitor.ts # Reminds agents of remaining headroom +├── rules-injector/ # Conditional rules +├── directory-agents-injector/ # Auto-injects AGENTS.md +├── directory-readme-injector/ # Auto-injects README.md +├── edit-error-recovery/ # Recovers from failures +├── thinking-block-validator/ # Ensures valid +├── context-window-monitor.ts # Reminds of headroom ├── session-recovery/ # Auto-recovers from crashes ├── think-mode/ # Dynamic thinking budget ├── keyword-detector/ # ultrawork/search/analyze modes -├── background-notification/ # OS notification on task completion -├── prometheus-md-only/ # Enforces planner read-only mode -├── agent-usage-reminder/ # Reminds to use specialized agents -├── auto-update-checker/ # Checks for plugin updates +├── background-notification/ # OS notification +├── prometheus-md-only/ # Planner read-only mode +├── agent-usage-reminder/ # Specialized agent hints +├── auto-update-checker/ # Plugin update check └── tool-output-truncator.ts # Prevents context bloat ``` @@ -36,41 +35,37 @@ hooks/ | Event | Timing | Can Block | Use Case | |-------|--------|-----------|----------| -| PreToolUse | Before tool | Yes | Validate/modify inputs, inject context | -| PostToolUse | After tool | No | Append warnings, truncate output | -| UserPromptSubmit | On prompt | Yes | Keyword detection, mode switching | -| Stop | Session idle | No | Auto-continue (todo-continuation, ralph-loop) | -| onSummarize | Compaction | No | Preserve critical state | +| PreToolUse | Before tool | Yes | Validate/modify inputs | +| PostToolUse | After tool | No | Append warnings, truncate | +| UserPromptSubmit | On prompt | Yes | Keyword detection | +| Stop | Session idle | No | Auto-continue | +| onSummarize | Compaction | No | Preserve state | ## EXECUTION ORDER **chat.message**: keywordDetector → claudeCodeHooks → autoSlashCommand → startWork → ralphLoop -**tool.execute.before**: claudeCodeHooks → nonInteractiveEnv → commentChecker → directoryAgentsInjector → directoryReadmeInjector → rulesInjector +**tool.execute.before**: claudeCodeHooks → nonInteractiveEnv → commentChecker → directoryAgentsInjector → rulesInjector -**tool.execute.after**: editErrorRecovery → delegateTaskRetry → commentChecker → toolOutputTruncator → emptyTaskResponseDetector → claudeCodeHooks +**tool.execute.after**: editErrorRecovery → delegateTaskRetry → commentChecker → toolOutputTruncator → claudeCodeHooks ## HOW TO ADD 1. Create `src/hooks/name/` with `index.ts` exporting `createMyHook(ctx)` -2. Implement event handlers: `"tool.execute.before"`, `"tool.execute.after"`, etc. -3. Add hook name to `HookNameSchema` in `src/config/schema.ts` -4. Register in `src/index.ts`: +2. Add hook name to `HookNameSchema` in `src/config/schema.ts` +3. Register in `src/index.ts`: ```typescript const myHook = isHookEnabled("my-hook") ? createMyHook(ctx) : null - // Add to event handlers ``` ## PATTERNS -- **Session-scoped state**: `Map>` for tracking per-session +- **Session-scoped state**: `Map>` - **Conditional execution**: Check `input.tool` before processing -- **Output modification**: `output.output += "\n${REMINDER}"` to append context -- **Async state**: Use promises for CLI path resolution, cache results +- **Output modification**: `output.output += "\n${REMINDER}"` ## ANTI-PATTERNS -- **Blocking non-critical**: Use PostToolUse warnings instead of PreToolUse blocks -- **Heavy computation**: Keep PreToolUse light - slows every tool call -- **Redundant injection**: Track injected files to prevent duplicates -- **Verbose output**: Keep hook messages technical, brief +- **Blocking non-critical**: Use PostToolUse warnings instead +- **Heavy computation**: Keep PreToolUse light +- **Redundant injection**: Track injected files diff --git a/src/hooks/claude-code-hooks/AGENTS.md b/src/hooks/claude-code-hooks/AGENTS.md index 1bb52a012..7e3496fc5 100644 --- a/src/hooks/claude-code-hooks/AGENTS.md +++ b/src/hooks/claude-code-hooks/AGENTS.md @@ -1,37 +1,36 @@ -# CLAUDE CODE HOOKS COMPATIBILITY LAYER +# CLAUDE CODE HOOKS COMPATIBILITY ## OVERVIEW -Full Claude Code settings.json hook compatibility. Executes user-defined hooks at 5 lifecycle events: PreToolUse, PostToolUse, UserPromptSubmit, Stop, PreCompact. +Full Claude Code settings.json hook compatibility. 5 lifecycle events: PreToolUse, PostToolUse, UserPromptSubmit, Stop, PreCompact. ## STRUCTURE ``` claude-code-hooks/ -├── index.ts # Main factory (401 lines) - createClaudeCodeHooksHook() +├── index.ts # Main factory (401 lines) ├── config.ts # Loads ~/.claude/settings.json -├── config-loader.ts # Extended config from multiple sources -├── pre-tool-use.ts # PreToolUse hook executor (172 lines) -├── post-tool-use.ts # PostToolUse hook executor (199 lines) -├── user-prompt-submit.ts # UserPromptSubmit hook executor -├── stop.ts # Stop hook executor (session idle) -├── pre-compact.ts # PreCompact hook executor (context compaction) -├── transcript.ts # Tool use recording (252 lines) -├── tool-input-cache.ts # Caches tool inputs between pre/post -├── types.ts # Hook types, context interfaces -├── todo.ts # Todo JSON parsing fix -└── plugin-config.ts # Plugin config access +├── config-loader.ts # Extended config +├── pre-tool-use.ts # PreToolUse executor +├── post-tool-use.ts # PostToolUse executor +├── user-prompt-submit.ts # UserPromptSubmit executor +├── stop.ts # Stop hook executor +├── pre-compact.ts # PreCompact executor +├── transcript.ts # Tool use recording +├── tool-input-cache.ts # Pre→post caching +├── types.ts # Hook types +└── todo.ts # Todo JSON fix ``` ## HOOK LIFECYCLE -| Event | When | Can Block | Context Fields | -|-------|------|-----------|----------------| -| **PreToolUse** | Before tool | Yes | sessionId, toolName, toolInput, cwd | -| **PostToolUse** | After tool | Warn only | + toolOutput, transcriptPath | -| **UserPromptSubmit** | On user message | Yes | sessionId, prompt, parts, cwd | -| **Stop** | Session idle | inject_prompt | sessionId, parentSessionId | -| **PreCompact** | Before summarize | No | sessionId, cwd | +| Event | When | Can Block | Context | +|-------|------|-----------|---------| +| PreToolUse | Before tool | Yes | sessionId, toolName, toolInput | +| PostToolUse | After tool | Warn | + toolOutput, transcriptPath | +| UserPromptSubmit | On message | Yes | sessionId, prompt, parts | +| Stop | Session idle | inject | sessionId, parentSessionId | +| PreCompact | Before summarize | No | sessionId | ## CONFIG SOURCES @@ -39,32 +38,14 @@ Priority (highest first): 1. `.claude/settings.json` (project) 2. `~/.claude/settings.json` (user) -```json -{ - "hooks": { - "PreToolUse": [{ "matcher": "Edit", "command": "./check.sh" }], - "PostToolUse": [{ "command": "post-hook.sh $TOOL_NAME" }] - } -} -``` - ## HOOK EXECUTION -1. User-defined hooks loaded from settings.json -2. Matchers filter by tool name (supports wildcards) -3. Commands executed via subprocess with environment: - - `$SESSION_ID`, `$TOOL_NAME`, `$TOOL_INPUT`, `$CWD` +1. Hooks loaded from settings.json +2. Matchers filter by tool name +3. Commands via subprocess with `$SESSION_ID`, `$TOOL_NAME` 4. Exit codes: 0=pass, 1=warn, 2=block -## KEY PATTERNS - -- **Session tracking**: `Map` for first-message, error, interrupt -- **Input caching**: Tool inputs cached pre→post via `tool-input-cache.ts` -- **Transcript recording**: All tool uses logged for debugging -- **Todowrite fix**: Parses string todos to array (line 174-196) - ## ANTI-PATTERNS -- **Heavy PreToolUse logic**: Runs before EVERY tool call -- **Blocking non-critical**: Use warnings in PostToolUse instead -- **Missing error handling**: Always wrap subprocess calls +- **Heavy PreToolUse**: Runs before EVERY tool call +- **Blocking non-critical**: Use PostToolUse warnings diff --git a/src/mcp/AGENTS.md b/src/mcp/AGENTS.md index 72974e933..a9dceae96 100644 --- a/src/mcp/AGENTS.md +++ b/src/mcp/AGENTS.md @@ -1,8 +1,8 @@ -# BUILT-IN MCP CONFIGURATIONS +# MCP KNOWLEDGE BASE ## OVERVIEW -3 remote MCP servers for web search, documentation, and code search. All use HTTP/SSE transport, no OAuth. +3 remote MCP servers: web search, documentation, code search. HTTP/SSE transport. ## STRUCTURE @@ -20,20 +20,19 @@ mcp/ | Name | URL | Purpose | Auth | |------|-----|---------|------| -| **websearch** | `mcp.exa.ai` | Real-time web search | `EXA_API_KEY` header | -| **context7** | `mcp.context7.com` | Official library docs | None | -| **grep_app** | `mcp.grep.app` | GitHub code search | None | +| websearch | mcp.exa.ai | Real-time web search | EXA_API_KEY | +| context7 | mcp.context7.com | Library docs | None | +| grep_app | mcp.grep.app | GitHub code search | None | ## CONFIG PATTERN -All MCPs follow identical structure: ```typescript export const mcp_name = { type: "remote" as const, url: "https://...", enabled: true, - oauth: false as const, // Explicit disable - headers?: { ... }, // Optional auth + oauth: false as const, + headers?: { ... }, } ``` @@ -42,29 +41,18 @@ export const mcp_name = { ```typescript import { createBuiltinMcps } from "./mcp" -// Enable all -const mcps = createBuiltinMcps() - -// Disable specific -const mcps = createBuiltinMcps(["websearch"]) +const mcps = createBuiltinMcps() // Enable all +const mcps = createBuiltinMcps(["websearch"]) // Disable specific ``` ## HOW TO ADD -1. Create `src/mcp/my-mcp.ts`: - ```typescript - export const my_mcp = { - type: "remote" as const, - url: "https://mcp.example.com", - enabled: true, - oauth: false as const, - } - ``` +1. Create `src/mcp/my-mcp.ts` 2. Add to `allBuiltinMcps` in `index.ts` 3. Add to `McpNameSchema` in `types.ts` ## NOTES -- **Remote only**: All built-in MCPs use HTTP/SSE, no stdio -- **Disable config**: User can disable via `disabled_mcps: ["name"]` -- **Exa requires key**: Set `EXA_API_KEY` env var for websearch +- **Remote only**: HTTP/SSE, no stdio +- **Disable**: User can set `disabled_mcps: ["name"]` +- **Exa**: Requires `EXA_API_KEY` env var diff --git a/src/shared/AGENTS.md b/src/shared/AGENTS.md index 0690bbe6c..458a93f68 100644 --- a/src/shared/AGENTS.md +++ b/src/shared/AGENTS.md @@ -2,75 +2,64 @@ ## OVERVIEW -50 cross-cutting utilities: path resolution, token truncation, config parsing, model resolution, Claude Code compatibility. +50 cross-cutting utilities: path resolution, token truncation, config parsing, model resolution. ## STRUCTURE ``` shared/ -├── logger.ts # File-based logging (tmpdir/oh-my-opencode.log) -├── permission-compat.ts # Agent tool restrictions (ask/allow/deny) -├── dynamic-truncator.ts # Token-aware truncation (50% headroom) -├── frontmatter.ts # YAML frontmatter parsing -├── jsonc-parser.ts # JSON with Comments support -├── data-path.ts # XDG-compliant storage (~/.local/share) -├── opencode-config-dir.ts # ~/.config/opencode resolution -├── claude-config-dir.ts # ~/.claude resolution -├── migration.ts # Legacy config migration (omo → Sisyphus) -├── opencode-version.ts # Version comparison (>= 1.0.150) +├── logger.ts # File-based logging +├── permission-compat.ts # Agent tool restrictions +├── dynamic-truncator.ts # Token-aware truncation +├── frontmatter.ts # YAML frontmatter +├── jsonc-parser.ts # JSON with Comments +├── data-path.ts # XDG-compliant storage +├── opencode-config-dir.ts # ~/.config/opencode +├── claude-config-dir.ts # ~/.claude +├── migration.ts # Legacy config migration +├── opencode-version.ts # Version comparison ├── external-plugin-detector.ts # OAuth spoofing detection -├── env-expander.ts # ${VAR} expansion in configs -├── system-directive.ts # System directive types -├── hook-utils.ts # Hook helper functions -├── model-requirements.ts # Agent/Category model requirements (providers + model) -├── model-availability.ts # Available models fetch + fuzzy matching -├── model-resolver.ts # 3-step model resolution (override → provider fallback → default) -├── shell-env.ts # Cross-platform shell environment -├── prompt-parts-helper.ts # Prompt parts manipulation -└── *.test.ts # Test files (colocated) +├── env-expander.ts # ${VAR} expansion +├── model-requirements.ts # Agent/Category requirements +├── model-availability.ts # Models fetch + fuzzy match +├── model-resolver.ts # 3-step resolution +├── shell-env.ts # Cross-platform shell +├── prompt-parts-helper.ts # Prompt manipulation +└── *.test.ts # Colocated tests ``` ## WHEN TO USE | Task | Utility | |------|---------| -| Debug logging | `log(message, data)` in `logger.ts` | +| Debug logging | `log(message, data)` | | Limit context | `dynamicTruncate(ctx, sessionId, output)` | | Parse frontmatter | `parseFrontmatter(content)` | -| Load JSONC config | `parseJsonc(text)` or `readJsoncFile(path)` | -| Restrict agent tools | `createAgentToolAllowlist(tools)` | -| Resolve paths | `getOpenCodeConfigDir()`, `getClaudeConfigDir()` | -| Migrate config | `migrateConfigFile(path, rawConfig)` | +| Load JSONC | `parseJsonc(text)` or `readJsoncFile(path)` | +| Restrict tools | `createAgentToolAllowlist(tools)` | +| Resolve paths | `getOpenCodeConfigDir()` | | Compare versions | `isOpenCodeVersionAtLeast("1.1.0")` | -| Get agent model requirements | `AGENT_MODEL_REQUIREMENTS` in `model-requirements.ts` | -| Get category model requirements | `CATEGORY_MODEL_REQUIREMENTS` in `model-requirements.ts` | -| Resolve model with fallback | `resolveModelWithFallback()` in `model-resolver.ts` | -| Fuzzy match model names | `fuzzyMatchModel()` in `model-availability.ts` | -| Fetch available models | `fetchAvailableModels(client)` in `model-availability.ts` | +| Resolve model | `resolveModelWithFallback()` | -## KEY PATTERNS +## PATTERNS ```typescript // Token-aware truncation -const { result } = await dynamicTruncate(ctx, sessionID, largeBuffer) +const { result } = await dynamicTruncate(ctx, sessionID, buffer) -// JSONC config loading +// JSONC config const settings = readJsoncFile(configPath) -// Version-gated features -if (isOpenCodeVersionAtLeast("1.1.0")) { /* new feature */ } +// Version-gated +if (isOpenCodeVersionAtLeast("1.1.0")) { /* ... */ } -// Tool permission normalization -const permissions = migrateToolsToPermission(legacyTools) - -// Model resolution with fallback chain +// Model resolution const model = await resolveModelWithFallback(client, requirements, override) ``` ## ANTI-PATTERNS -- **Raw JSON.parse**: Use `jsonc-parser.ts` for config files -- **Hardcoded paths**: Use `*-config-dir.ts` utilities -- **console.log**: Use `logger.ts` for background agents -- **Unbounded output**: Always use `dynamic-truncator.ts` -- **Manual version parse**: Use `opencode-version.ts` +- **Raw JSON.parse**: Use `jsonc-parser.ts` +- **Hardcoded paths**: Use `*-config-dir.ts` +- **console.log**: Use `logger.ts` for background +- **Unbounded output**: Use `dynamic-truncator.ts` diff --git a/src/tools/AGENTS.md b/src/tools/AGENTS.md index 7b5c2bed2..3e7b0ac01 100644 --- a/src/tools/AGENTS.md +++ b/src/tools/AGENTS.md @@ -2,7 +2,7 @@ ## OVERVIEW -20+ tools: LSP (6), AST-Grep (2), Search (2), Session (4), Agent delegation (4), System (2), Skill (3). High-performance C++ bindings via @ast-grep/napi. +20+ tools: LSP (6), AST-Grep (2), Search (2), Session (4), Agent delegation (4), System (2), Skill (3). ## STRUCTURE @@ -10,17 +10,17 @@ tools/ ├── [tool-name]/ │ ├── index.ts # Barrel export -│ ├── tools.ts # Business logic, ToolDefinition +│ ├── tools.ts # ToolDefinition │ ├── types.ts # Zod schemas -│ └── constants.ts # Fixed values, descriptions -├── lsp/ # 6 tools: goto_definition, references, symbols, diagnostics, prepare_rename, rename -├── ast-grep/ # 2 tools: search, replace (25 languages via NAPI) -├── delegate-task/ # Category-based agent routing (1027 lines) +│ └── constants.ts # Fixed values +├── lsp/ # 6 tools: definition, references, symbols, diagnostics, rename +├── ast-grep/ # 2 tools: search, replace (25 languages) +├── delegate-task/ # Category-based routing (1038 lines) ├── session-manager/ # 4 tools: list, read, search, info -├── grep/ # Custom grep with timeout/truncation -├── glob/ # Custom glob with 60s timeout, 100 file limit +├── grep/ # Custom grep with timeout +├── glob/ # 60s timeout, 100 file limit ├── interactive-bash/ # Tmux session management -├── look-at/ # Multimodal PDF/image analysis +├── look-at/ # Multimodal PDF/image ├── skill/ # Skill execution ├── skill-mcp/ # Skill MCP operations ├── slashcommand/ # Slash command dispatch @@ -32,43 +32,33 @@ tools/ | Category | Tools | Purpose | |----------|-------|---------| -| **LSP** | lsp_goto_definition, lsp_find_references, lsp_symbols, lsp_diagnostics, lsp_prepare_rename, lsp_rename | Semantic code intelligence | -| **Search** | ast_grep_search, ast_grep_replace, grep, glob | Pattern discovery | -| **Session** | session_list, session_read, session_search, session_info | History navigation | -| **Agent** | delegate_task, call_omo_agent, background_output, background_cancel | Task orchestration | -| **System** | interactive_bash, look_at | CLI, multimodal | -| **Skill** | skill, skill_mcp, slashcommand | Skill execution | +| LSP | lsp_goto_definition, lsp_find_references, lsp_symbols, lsp_diagnostics, lsp_prepare_rename, lsp_rename | Semantic code intelligence | +| Search | ast_grep_search, ast_grep_replace, grep, glob | Pattern discovery | +| Session | session_list, session_read, session_search, session_info | History navigation | +| Agent | delegate_task, call_omo_agent, background_output, background_cancel | Task orchestration | +| System | interactive_bash, look_at | CLI, multimodal | +| Skill | skill, skill_mcp, slashcommand | Skill execution | ## HOW TO ADD 1. Create `src/tools/[name]/` with standard files -2. Use `tool()` from `@opencode-ai/plugin/tool`: - ```typescript - export const myTool: ToolDefinition = tool({ - description: "...", - args: { param: tool.schema.string() }, - execute: async (args) => { /* ... */ } - }) - ``` +2. Use `tool()` from `@opencode-ai/plugin/tool` 3. Export from `src/tools/index.ts` 4. Add to `builtinTools` object ## LSP SPECIFICS -- **Client**: `client.ts` manages stdio lifecycle, JSON-RPC +- **Client**: `client.ts` manages stdio, JSON-RPC - **Singleton**: `LSPServerManager` with ref counting -- **Protocol**: Standard LSP methods mapped to tool responses - **Capabilities**: definition, references, symbols, diagnostics, rename ## AST-GREP SPECIFICS - **Engine**: `@ast-grep/napi` for 25+ languages -- **Patterns**: Meta-variables `$VAR` (single), `$$$` (multiple) -- **Performance**: Rust/C++ layer for structural matching +- **Patterns**: `$VAR` (single), `$$$` (multiple) ## ANTI-PATTERNS -- **Sequential bash**: Use `&&` or delegation, not loops +- **Sequential bash**: Use `&&` or delegation - **Raw file ops**: Never mkdir/touch in tool logic -- **Sleep**: Use polling loops, tool-specific wait flags -- **Heavy sync**: Keep PreToolUse light, computation in tools.ts +- **Sleep**: Use polling loops