chore(docs): regenerate AGENTS.md knowledge base (#1118)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: justsisyphus <justsisyphus@users.noreply.github.com> Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
48
AGENTS.md
48
AGENTS.md
@@ -1,12 +1,24 @@
|
||||
# PROJECT KNOWLEDGE BASE
|
||||
|
||||
**Generated:** 2026-01-25T13:10:00+09:00
|
||||
**Commit:** 043b1a33
|
||||
**Generated:** 2026-01-25T18:08:00+09:00
|
||||
**Commit:** 1d68757f
|
||||
**Branch:** dev
|
||||
|
||||
---
|
||||
|
||||
## **IMPORTANT: PULL REQUEST TARGET BRANCH**
|
||||
|
||||
> **ALL PULL REQUESTS MUST TARGET THE `dev` BRANCH.**
|
||||
>
|
||||
> **DO NOT CREATE PULL REQUESTS TARGETING `master` BRANCH.**
|
||||
>
|
||||
> PRs to `master` will be automatically rejected by CI.
|
||||
|
||||
---
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
OpenCode plugin: multi-model agent orchestration (Claude Opus 4.5, GPT-5.2, Gemini 3 Flash, Grok Code, GLM-4.7). 31 lifecycle hooks, 20+ tools (LSP, AST-Grep, delegation), 10 specialized agents, full Claude Code compatibility. "oh-my-zsh" for OpenCode.
|
||||
OpenCode plugin: multi-model agent orchestration (Claude Opus 4.5, GPT-5.2, Gemini 3 Flash, Grok Code). 32 lifecycle hooks, 20+ tools (LSP, AST-Grep, delegation), 10 specialized agents, full Claude Code compatibility. "oh-my-zsh" for OpenCode.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
@@ -14,14 +26,14 @@ OpenCode plugin: multi-model agent orchestration (Claude Opus 4.5, GPT-5.2, Gemi
|
||||
oh-my-opencode/
|
||||
├── src/
|
||||
│ ├── agents/ # 10 AI agents - see src/agents/AGENTS.md
|
||||
│ ├── hooks/ # 31 lifecycle hooks - see src/hooks/AGENTS.md
|
||||
│ ├── hooks/ # 32 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
|
||||
│ ├── shared/ # 55 cross-cutting utilities - see src/shared/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 (601 lines)
|
||||
│ └── index.ts # Main plugin entry (669 lines)
|
||||
├── script/ # build-schema.ts, build-binaries.ts
|
||||
├── packages/ # 7 platform-specific binaries
|
||||
└── dist/ # Build output (ESM + .d.ts)
|
||||
@@ -38,8 +50,8 @@ oh-my-opencode/
|
||||
| Add skill | `src/features/builtin-skills/` | Create dir with SKILL.md |
|
||||
| Add command | `src/features/builtin-commands/` | Add template + register in commands.ts |
|
||||
| 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 (773 lines) |
|
||||
| Background agents | `src/features/background-agent/` | manager.ts (1377 lines) |
|
||||
| Orchestrator | `src/hooks/atlas/` | Main orchestration hook (752 lines) |
|
||||
|
||||
## TDD (Test-Driven Development)
|
||||
|
||||
@@ -51,8 +63,8 @@ oh-my-opencode/
|
||||
**Rules:**
|
||||
- NEVER write implementation before test
|
||||
- NEVER delete failing tests - fix the code
|
||||
- Test file: `*.test.ts` alongside source
|
||||
- BDD comments: `#given`, `#when`, `#then`
|
||||
- Test file: `*.test.ts` alongside source (100 test files)
|
||||
- BDD comments: `//#given`, `//#when`, `//#then`
|
||||
|
||||
## CONVENTIONS
|
||||
|
||||
@@ -61,7 +73,7 @@ oh-my-opencode/
|
||||
- **Build**: `bun build` (ESM) + `tsc --emitDeclarationOnly`
|
||||
- **Exports**: Barrel pattern via index.ts
|
||||
- **Naming**: kebab-case dirs, `createXXXHook`/`createXXXTool` factories
|
||||
- **Testing**: BDD comments, 95 test files
|
||||
- **Testing**: BDD comments, 100 test files
|
||||
- **Temperature**: 0.1 for code agents, max 0.3
|
||||
|
||||
## ANTI-PATTERNS
|
||||
@@ -100,7 +112,7 @@ oh-my-opencode/
|
||||
bun run typecheck # Type check
|
||||
bun run build # ESM + declarations + schema
|
||||
bun run rebuild # Clean + Build
|
||||
bun test # 95 test files
|
||||
bun test # 100 test files
|
||||
```
|
||||
|
||||
## DEPLOYMENT
|
||||
@@ -114,16 +126,14 @@ bun test # 95 test files
|
||||
|
||||
| File | Lines | Description |
|
||||
|------|-------|-------------|
|
||||
| `src/features/background-agent/manager.ts` | 1335 | Task lifecycle, concurrency |
|
||||
| `src/features/builtin-skills/skills.ts` | 1203 | Skill definitions |
|
||||
| `src/features/builtin-skills/skills.ts` | 1729 | Skill definitions |
|
||||
| `src/features/background-agent/manager.ts` | 1377 | Task lifecycle, concurrency |
|
||||
| `src/agents/prometheus-prompt.ts` | 1196 | Planning agent |
|
||||
| `src/tools/delegate-task/tools.ts` | 1039 | Category-based delegation |
|
||||
| `src/hooks/atlas/index.ts` | 773 | Orchestrator hook |
|
||||
| `src/tools/delegate-task/tools.ts` | 1070 | Category-based delegation |
|
||||
| `src/hooks/atlas/index.ts` | 752 | Orchestrator hook |
|
||||
| `src/cli/config-manager.ts` | 664 | JSONC config parsing |
|
||||
| `src/index.ts` | 669 | Main plugin entry |
|
||||
| `src/features/builtin-commands/templates/refactor.ts` | 619 | Refactor command template |
|
||||
| `src/index.ts` | 601 | Main plugin entry |
|
||||
| `src/tools/lsp/client.ts` | 596 | LSP JSON-RPC client |
|
||||
| `src/agents/atlas.ts` | 572 | Atlas orchestrator agent |
|
||||
|
||||
## MCP ARCHITECTURE
|
||||
|
||||
|
||||
@@ -1,31 +1,27 @@
|
||||
# AGENTS KNOWLEDGE BASE
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
10 AI agents for multi-model orchestration. Sisyphus (primary), Atlas (orchestrator), oracle, librarian, explore, multimodal-looker, Prometheus, Metis, Momus, Sisyphus-Junior.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
agents/
|
||||
├── atlas.ts # Master Orchestrator (572 lines)
|
||||
├── sisyphus.ts # Main prompt (450 lines)
|
||||
├── sisyphus-junior.ts # Delegated task executor (135 lines)
|
||||
├── dynamic-agent-prompt-builder.ts # Dynamic prompt generation (359 lines)
|
||||
├── atlas.ts # Master Orchestrator (holds todo list)
|
||||
├── sisyphus.ts # Main prompt (SF Bay Area engineer identity)
|
||||
├── sisyphus-junior.ts # Delegated task executor (category-spawned)
|
||||
├── oracle.ts # Strategic advisor (GPT-5.2)
|
||||
├── librarian.ts # Multi-repo research (326 lines)
|
||||
├── explore.ts # Fast grep (Grok Code)
|
||||
├── librarian.ts # Multi-repo research (GitHub CLI, Context7)
|
||||
├── explore.ts # Fast contextual grep (Grok Code)
|
||||
├── multimodal-looker.ts # Media analyzer (Gemini 3 Flash)
|
||||
├── prometheus-prompt.ts # Planning (1196 lines)
|
||||
├── metis.ts # Plan consultant (315 lines)
|
||||
├── momus.ts # Plan reviewer (444 lines)
|
||||
├── prometheus-prompt.ts # Planning (Interview/Consultant mode, 1196 lines)
|
||||
├── metis.ts # Pre-planning analysis (Gap detection)
|
||||
├── momus.ts # Plan reviewer (Ruthless fault-finding)
|
||||
├── types.ts # AgentModelConfig, AgentPromptMetadata
|
||||
├── utils.ts # createBuiltinAgents(), resolveModelWithFallback()
|
||||
└── index.ts # builtinAgents export
|
||||
```
|
||||
|
||||
## AGENT MODELS
|
||||
|
||||
| Agent | Model | Temp | Purpose |
|
||||
|-------|-------|------|---------|
|
||||
| Sisyphus | anthropic/claude-opus-4-5 | 0.1 | Primary orchestrator |
|
||||
@@ -40,14 +36,12 @@ agents/
|
||||
| Sisyphus-Junior | anthropic/claude-sonnet-4-5 | 0.1 | Category-spawned executor |
|
||||
|
||||
## HOW TO ADD
|
||||
|
||||
1. Create `src/agents/my-agent.ts` exporting factory + metadata
|
||||
2. Add to `agentSources` in `src/agents/utils.ts`
|
||||
3. Update `AgentNameSchema` in `src/config/schema.ts`
|
||||
4. Register in `src/index.ts` initialization
|
||||
1. Create `src/agents/my-agent.ts` exporting factory + metadata.
|
||||
2. Add to `agentSources` in `src/agents/utils.ts`.
|
||||
3. Update `AgentNameSchema` in `src/config/schema.ts`.
|
||||
4. Register in `src/index.ts` initialization.
|
||||
|
||||
## TOOL RESTRICTIONS
|
||||
|
||||
| Agent | Denied Tools |
|
||||
|-------|-------------|
|
||||
| oracle | write, edit, task, delegate_task |
|
||||
@@ -57,14 +51,13 @@ agents/
|
||||
| Sisyphus-Junior | task, delegate_task |
|
||||
|
||||
## PATTERNS
|
||||
|
||||
- **Factory**: `createXXXAgent(model?: string): AgentConfig`
|
||||
- **Metadata**: `XXX_PROMPT_METADATA` with category, cost, triggers
|
||||
- **Tool restrictions**: `createAgentToolRestrictions(tools)` or `createAgentToolAllowlist(tools)`
|
||||
- **Thinking**: 32k budget tokens for Sisyphus, Oracle, Prometheus, Atlas
|
||||
- **Factory**: `createXXXAgent(model: string): AgentConfig`
|
||||
- **Metadata**: `XXX_PROMPT_METADATA` with category, cost, triggers.
|
||||
- **Tool restrictions**: `createAgentToolRestrictions(tools)` or `createAgentToolAllowlist(tools)`.
|
||||
- **Thinking**: 32k budget tokens for Sisyphus, Oracle, Prometheus, Atlas.
|
||||
|
||||
## ANTI-PATTERNS
|
||||
|
||||
- **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`
|
||||
- **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` for exploration.
|
||||
- **Prometheus writing code**: Planner only - never implements.
|
||||
|
||||
@@ -8,7 +8,7 @@ CLI entry: `bunx oh-my-opencode`. Interactive installer, doctor diagnostics. Com
|
||||
|
||||
```
|
||||
cli/
|
||||
├── index.ts # Commander.js entry
|
||||
├── index.ts # Commander.js entry (4 commands)
|
||||
├── install.ts # Interactive TUI (520 lines)
|
||||
├── config-manager.ts # JSONC parsing (664 lines)
|
||||
├── types.ts # InstallArgs, InstallConfig
|
||||
@@ -18,7 +18,7 @@ cli/
|
||||
│ ├── runner.ts # Check orchestration
|
||||
│ ├── formatter.ts # Colored output
|
||||
│ ├── constants.ts # Check IDs, symbols
|
||||
│ ├── types.ts # CheckResult, CheckDefinition
|
||||
│ ├── types.ts # CheckResult, CheckDefinition (114 lines)
|
||||
│ └── checks/ # 14 checks, 21 files
|
||||
│ ├── version.ts # OpenCode + plugin version
|
||||
│ ├── config.ts # JSONC validity, Zod
|
||||
@@ -38,36 +38,37 @@ cli/
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `install` | Interactive setup |
|
||||
| `doctor` | 14 health checks |
|
||||
| `run` | Launch session |
|
||||
| `get-local-version` | Version check |
|
||||
| `install` | Interactive setup with provider selection |
|
||||
| `doctor` | 14 health checks for diagnostics |
|
||||
| `run` | Launch session with todo enforcement |
|
||||
| `get-local-version` | Version detection and update check |
|
||||
|
||||
## DOCTOR CATEGORIES
|
||||
## DOCTOR CATEGORIES (14 Checks)
|
||||
|
||||
| Category | Checks |
|
||||
|----------|--------|
|
||||
| installation | opencode, plugin |
|
||||
| configuration | config validity, Zod |
|
||||
| configuration | config validity, Zod, model-resolution |
|
||||
| authentication | anthropic, openai, google |
|
||||
| dependencies | ast-grep, comment-checker |
|
||||
| dependencies | ast-grep, comment-checker, gh-cli |
|
||||
| tools | LSP, MCP |
|
||||
| updates | version comparison |
|
||||
|
||||
## HOW TO ADD CHECK
|
||||
|
||||
1. Create `src/cli/doctor/checks/my-check.ts`
|
||||
2. Export from `checks/index.ts`
|
||||
3. Add to `getAllCheckDefinitions()`
|
||||
2. Export `getXXXCheckDefinition()` factory returning `CheckDefinition`
|
||||
3. Add to `getAllCheckDefinitions()` in `checks/index.ts`
|
||||
|
||||
## TUI FRAMEWORK
|
||||
|
||||
- **@clack/prompts**: `select()`, `spinner()`, `intro()`
|
||||
- **picocolors**: Terminal colors
|
||||
- **Symbols**: ✓ (pass), ✗ (fail), ⚠ (warn)
|
||||
- **@clack/prompts**: `select()`, `spinner()`, `intro()`, `outro()`
|
||||
- **picocolors**: Terminal colors for status and headers
|
||||
- **Symbols**: ✓ (pass), ✗ (fail), ⚠ (warn), ℹ (info)
|
||||
|
||||
## ANTI-PATTERNS
|
||||
|
||||
- **Blocking in non-TTY**: Check `process.stdout.isTTY`
|
||||
- **Direct JSON.parse**: Use `parseJsonc()`
|
||||
- **Silent failures**: Return warn/fail in doctor
|
||||
- **Blocking in non-TTY**: Always check `process.stdout.isTTY`
|
||||
- **Direct JSON.parse**: Use `parseJsonc()` from shared utils
|
||||
- **Silent failures**: Return `warn` or `fail` in doctor instead of throwing
|
||||
- **Hardcoded paths**: Use `getOpenCodeConfigPaths()` from `config-manager.ts`
|
||||
|
||||
@@ -2,24 +2,18 @@
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
Core feature modules + Claude Code compatibility layer. Background agents, skill MCP, builtin skills/commands, 5 loaders.
|
||||
Core feature modules + Claude Code compatibility layer. Orchestrates background agents, skill MCPs, builtin skills/commands, and 16 feature modules.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
features/
|
||||
├── background-agent/ # Task lifecycle (1335 lines)
|
||||
├── background-agent/ # Task lifecycle (1377 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, cleanup
|
||||
│ └── types.ts # SkillMcpConfig
|
||||
├── builtin-skills/ # Playwright, git-master, frontend-ui-ux
|
||||
│ └── skills.ts # 1203 lines
|
||||
├── builtin-commands/ # ralph-loop, refactor, init-deep, start-work, remove-deadcode
|
||||
│ ├── commands.ts # Command registry
|
||||
│ └── templates/ # Command templates (4 files)
|
||||
│ └── concurrency.ts # Per-provider limits
|
||||
├── builtin-skills/ # Core skills (1729 lines)
|
||||
│ └── skills.ts # agent-browser, dev-browser, frontend-ui-ux, git-master, typescript-programmer
|
||||
├── builtin-commands/ # ralph-loop, refactor, ulw-loop, init-deep
|
||||
├── claude-code-agent-loader/ # ~/.claude/agents/*.md
|
||||
├── claude-code-command-loader/ # ~/.claude/commands/*.md
|
||||
├── claude-code-mcp-loader/ # .mcp.json
|
||||
@@ -29,7 +23,10 @@ features/
|
||||
├── context-injector/ # AGENTS.md/README.md injection
|
||||
├── boulder-state/ # Todo state persistence
|
||||
├── hook-message-injector/ # Message injection
|
||||
└── task-toast-manager/ # Background task notifications
|
||||
├── task-toast-manager/ # Background task notifications
|
||||
├── skill-mcp-manager/ # MCP client lifecycle (520 lines)
|
||||
├── tmux-subagent/ # Tmux session management
|
||||
└── ... (16 modules total)
|
||||
```
|
||||
|
||||
## LOADER PRIORITY
|
||||
@@ -44,8 +41,9 @@ features/
|
||||
|
||||
- **Lifecycle**: `launch` → `poll` (2s) → `complete`
|
||||
- **Stability**: 3 consecutive polls = idle
|
||||
- **Concurrency**: Per-provider/model limits
|
||||
- **Concurrency**: Per-provider/model limits via `ConcurrencyManager`
|
||||
- **Cleanup**: 30m TTL, 3m stale timeout
|
||||
- **State**: Per-session Maps, cleaned on `session.deleted`
|
||||
|
||||
## SKILL MCP
|
||||
|
||||
@@ -58,3 +56,4 @@ features/
|
||||
- **Sequential delegation**: Use `delegate_task` parallel
|
||||
- **Trust self-reports**: ALWAYS verify
|
||||
- **Main thread blocks**: No heavy I/O in loader init
|
||||
- **Direct state mutation**: Use managers for boulder/session state
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
# HOOKS KNOWLEDGE BASE
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
31 lifecycle hooks intercepting/modifying agent behavior. Events: PreToolUse, PostToolUse, UserPromptSubmit, Stop, onSummarize.
|
||||
32 lifecycle hooks intercepting/modifying agent behavior. Events: PreToolUse, PostToolUse, UserPromptSubmit, Stop, onSummarize.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
hooks/
|
||||
├── atlas/ # Main orchestration (773 lines)
|
||||
├── anthropic-context-window-limit-recovery/ # Auto-summarize
|
||||
├── todo-continuation-enforcer.ts # Force TODO completion (489 lines)
|
||||
├── atlas/ # Main orchestration (752 lines)
|
||||
├── anthropic-context-window-limit-recovery/ # Auto-summarize
|
||||
├── todo-continuation-enforcer.ts # Force TODO completion
|
||||
├── ralph-loop/ # Self-referential dev loop
|
||||
├── claude-code-hooks/ # settings.json compat layer - see AGENTS.md
|
||||
├── comment-checker/ # Prevents AI slop
|
||||
@@ -35,45 +33,63 @@ hooks/
|
||||
├── non-interactive-env/ # Non-TTY environment handling
|
||||
├── start-work/ # Sisyphus work session starter
|
||||
├── task-resume-info/ # Resume info for cancelled tasks
|
||||
├── question-label-truncator/ # Auto-truncates question labels >30 chars
|
||||
├── question-label-truncator/ # Auto-truncates question labels
|
||||
├── category-skill-reminder/ # Reminds of category skills
|
||||
├── empty-task-response-detector.ts # Detects empty responses
|
||||
├── sisyphus-junior-notepad/ # Sisyphus Junior notepad
|
||||
└── index.ts # Hook aggregation + registration
|
||||
```
|
||||
|
||||
## HOOK EVENTS
|
||||
|
||||
| Event | Timing | Can Block | Use Case |
|
||||
|-------|--------|-----------|----------|
|
||||
| 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 |
|
||||
| UserPromptSubmit | `chat.message` | Yes | Keyword detection, slash commands |
|
||||
| PreToolUse | `tool.execute.before` | Yes | Validate/modify inputs, inject context |
|
||||
| PostToolUse | `tool.execute.after` | No | Truncate output, error recovery |
|
||||
| Stop | `event` (session.stop) | No | Auto-continue, notifications |
|
||||
| onSummarize | Compaction | No | Preserve state, inject summary context |
|
||||
|
||||
## EXECUTION ORDER
|
||||
- **UserPromptSubmit**: keywordDetector → claudeCodeHooks → autoSlashCommand → startWork
|
||||
- **PreToolUse**: questionLabelTruncator → claudeCodeHooks → nonInteractiveEnv → commentChecker → directoryAgentsInjector → directoryReadmeInjector → rulesInjector → prometheusMdOnly → sisyphusJuniorNotepad → atlasHook
|
||||
- **PostToolUse**: claudeCodeHooks → toolOutputTruncator → contextWindowMonitor → commentChecker → directoryAgentsInjector → directoryReadmeInjector → rulesInjector → emptyTaskResponseDetector → agentUsageReminder → interactiveBashSession → editErrorRecovery → delegateTaskRetry → atlasHook → taskResumeInfo
|
||||
|
||||
**chat.message**: keywordDetector → claudeCodeHooks → autoSlashCommand → startWork → ralphLoop
|
||||
## CRITICAL DEPENDENCIES
|
||||
|
||||
**tool.execute.before**: claudeCodeHooks → nonInteractiveEnv → commentChecker → directoryAgentsInjector → rulesInjector
|
||||
|
||||
**tool.execute.after**: editErrorRecovery → delegateTaskRetry → commentChecker → toolOutputTruncator → claudeCodeHooks
|
||||
| Hook | Depends On | State Sharing |
|
||||
|------|------------|---------------|
|
||||
| todo-continuation-enforcer | session-recovery callbacks | `isRecovering` flag |
|
||||
| atlas | backgroundManager | Running task checks |
|
||||
| start-work | boulder state file | `.sisyphus/boulder.json` |
|
||||
| directory-*-injector | per-session caches | `sessionCaches` Map |
|
||||
|
||||
## HOW TO ADD
|
||||
|
||||
1. Create `src/hooks/name/` with `index.ts` exporting `createMyHook(ctx)`
|
||||
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
|
||||
```
|
||||
3. Register in `src/index.ts` and add to relevant lifecycle methods
|
||||
|
||||
## PATTERNS
|
||||
## HOOK PATTERNS
|
||||
|
||||
- **Session-scoped state**: `Map<sessionID, Set<string>>`
|
||||
- **Conditional execution**: Check `input.tool` before processing
|
||||
- **Output modification**: `output.output += "\n${REMINDER}"`
|
||||
**Simple Single-Event**:
|
||||
```typescript
|
||||
export function createToolOutputTruncatorHook(ctx) {
|
||||
return { "tool.execute.after": async (input, output) => { ... } }
|
||||
}
|
||||
```
|
||||
|
||||
**Multi-Event with State**:
|
||||
```typescript
|
||||
export function createThinkModeHook() {
|
||||
const state = new Map<string, ThinkModeState>()
|
||||
return {
|
||||
"chat.params": async (output, sessionID) => { ... },
|
||||
"event": async ({ event }) => { /* cleanup */ }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ANTI-PATTERNS
|
||||
|
||||
- **Blocking non-critical**: Use PostToolUse warnings instead
|
||||
- **Heavy computation**: Keep PreToolUse light
|
||||
- **Redundant injection**: Track injected files
|
||||
- **Heavy computation**: Keep PreToolUse light to avoid latency
|
||||
- **Redundant injection**: Track injected files to avoid context bloat
|
||||
- **Direct state mutation**: Use `output.output +=` instead of replacing
|
||||
|
||||
@@ -1,51 +1,48 @@
|
||||
# CLAUDE CODE HOOKS COMPATIBILITY
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
Full Claude Code settings.json hook compatibility. 5 lifecycle events: PreToolUse, PostToolUse, UserPromptSubmit, Stop, PreCompact.
|
||||
Full Claude Code `settings.json` hook compatibility layer. Intercepts OpenCode events to execute external scripts/commands defined in Claude Code configuration.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
claude-code-hooks/
|
||||
├── index.ts # Main factory (401 lines)
|
||||
├── config.ts # Loads ~/.claude/settings.json
|
||||
├── config-loader.ts # Extended config
|
||||
├── config-loader.ts # Extended config (disabledHooks)
|
||||
├── pre-tool-use.ts # PreToolUse executor
|
||||
├── post-tool-use.ts # PostToolUse executor
|
||||
├── user-prompt-submit.ts # UserPromptSubmit executor
|
||||
├── stop.ts # Stop hook executor
|
||||
├── stop.ts # Stop hook executor (with active state tracking)
|
||||
├── 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
|
||||
├── tool-input-cache.ts # Pre→post input caching
|
||||
└── types.ts # Hook & IO type definitions
|
||||
```
|
||||
|
||||
## HOOK LIFECYCLE
|
||||
|
||||
| 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 |
|
||||
| Event | Timing | Can Block | Context Provided |
|
||||
|-------|--------|-----------|------------------|
|
||||
| PreToolUse | Before tool exec | Yes | sessionId, toolName, toolInput, cwd |
|
||||
| PostToolUse | After tool exec | Warn | + toolOutput, transcriptPath |
|
||||
| UserPromptSubmit | On message send | Yes | sessionId, prompt, parts, cwd |
|
||||
| Stop | Session idle/end | Inject | sessionId, parentSessionId, cwd |
|
||||
| PreCompact | Before summarize | No | sessionId, cwd |
|
||||
|
||||
## CONFIG SOURCES
|
||||
|
||||
Priority (highest first):
|
||||
1. `.claude/settings.json` (project)
|
||||
2. `~/.claude/settings.json` (user)
|
||||
1. `.claude/settings.json` (Project-local)
|
||||
2. `~/.claude/settings.json` (Global user)
|
||||
|
||||
## HOOK EXECUTION
|
||||
|
||||
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
|
||||
- **Matchers**: Hooks filter by tool name or event type via regex/glob.
|
||||
- **Commands**: Executed via subprocess with env vars (`$SESSION_ID`, `$TOOL_NAME`).
|
||||
- **Exit Codes**:
|
||||
- `0`: Pass (Success)
|
||||
- `1`: Warn (Continue with system message)
|
||||
- `2`: Block (Abort operation/prompt)
|
||||
|
||||
## ANTI-PATTERNS
|
||||
|
||||
- **Heavy PreToolUse**: Runs before EVERY tool call
|
||||
- **Blocking non-critical**: Use PostToolUse warnings
|
||||
- **Heavy PreToolUse**: Runs before EVERY tool; keep logic light to avoid latency.
|
||||
- **Blocking non-critical**: Prefer PostToolUse warnings for non-fatal issues.
|
||||
- **Direct state mutation**: Use `updatedInput` in PreToolUse instead of side effects.
|
||||
- **Ignoring Exit Codes**: Ensure scripts return `2` to properly block sensitive tools.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
3 remote MCP servers: web search, documentation, code search. HTTP/SSE transport.
|
||||
3 remote MCP servers: web search, documentation, code search. HTTP/SSE transport. Part of three-tier MCP system.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
@@ -20,10 +20,16 @@ mcp/
|
||||
|
||||
| Name | URL | Purpose | Auth |
|
||||
|------|-----|---------|------|
|
||||
| websearch | mcp.exa.ai | Real-time web search | EXA_API_KEY |
|
||||
| context7 | mcp.context7.com | Library docs | None |
|
||||
| websearch | mcp.exa.ai/mcp?tools=web_search_exa | Real-time web search | EXA_API_KEY |
|
||||
| context7 | mcp.context7.com/mcp | Library docs | None |
|
||||
| grep_app | mcp.grep.app | GitHub code search | None |
|
||||
|
||||
## THREE-TIER MCP SYSTEM
|
||||
|
||||
1. **Built-in** (this directory): websearch, context7, grep_app
|
||||
2. **Claude Code compat**: `.mcp.json` with `${VAR}` expansion
|
||||
3. **Skill-embedded**: YAML frontmatter in skills (handled by skill-mcp-manager)
|
||||
|
||||
## CONFIG PATTERN
|
||||
|
||||
```typescript
|
||||
@@ -54,5 +60,5 @@ const mcps = createBuiltinMcps(["websearch"]) // Disable specific
|
||||
## NOTES
|
||||
|
||||
- **Remote only**: HTTP/SSE, no stdio
|
||||
- **Disable**: User can set `disabled_mcps: ["name"]`
|
||||
- **Disable**: User can set `disabled_mcps: ["name"]` in config
|
||||
- **Exa**: Requires `EXA_API_KEY` env var
|
||||
|
||||
@@ -1,81 +1,78 @@
|
||||
# SHARED UTILITIES KNOWLEDGE BASE
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
34 cross-cutting utilities: path resolution, token truncation, config parsing, model resolution, agent display names.
|
||||
55 cross-cutting utilities: path resolution, token truncation, config parsing, model resolution.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
shared/
|
||||
├── 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
|
||||
├── model-requirements.ts # Agent/Category requirements
|
||||
├── model-availability.ts # Models fetch + fuzzy match
|
||||
├── model-resolver.ts # 3-step resolution
|
||||
├── model-sanitizer.ts # Model ID normalization
|
||||
├── shell-env.ts # Cross-platform shell
|
||||
├── agent-display-names.ts # Agent display name mapping
|
||||
├── agent-tool-restrictions.ts # Tool restriction helpers
|
||||
├── agent-variant.ts # Agent variant detection
|
||||
├── command-executor.ts # Subprocess execution
|
||||
├── config-errors.ts # Config error types
|
||||
├── deep-merge.ts # Deep object merge
|
||||
├── file-reference-resolver.ts # File path resolution
|
||||
├── file-utils.ts # File utilities
|
||||
├── hook-disabled.ts # Hook enable/disable check
|
||||
├── pattern-matcher.ts # Glob pattern matching
|
||||
├── session-cursor.ts # Session cursor tracking
|
||||
├── snake-case.ts # String case conversion
|
||||
├── system-directive.ts # System prompt helpers
|
||||
├── tool-name.ts # Tool name constants
|
||||
├── zip-extractor.ts # ZIP file extraction
|
||||
├── index.ts # Barrel export
|
||||
└── *.test.ts # Colocated tests
|
||||
├── tmux/ # Tmux TUI integration (types, utils, constants)
|
||||
├── logger.ts # File-based logging (/tmp/oh-my-opencode.log)
|
||||
├── dynamic-truncator.ts # Token-aware context window management (194 lines)
|
||||
├── model-resolver.ts # 3-step resolution (Override → Fallback → Default)
|
||||
├── model-requirements.ts # Agent/category model fallback chains (132 lines)
|
||||
├── model-availability.ts # Provider model fetching & fuzzy matching (154 lines)
|
||||
├── jsonc-parser.ts # JSONC parsing with comment support
|
||||
├── frontmatter.ts # YAML frontmatter extraction (JSON_SCHEMA only)
|
||||
├── data-path.ts # XDG-compliant storage resolution
|
||||
├── opencode-config-dir.ts # ~/.config/opencode resolution (143 lines)
|
||||
├── claude-config-dir.ts # ~/.claude resolution
|
||||
├── migration.ts # Legacy config migration logic (231 lines)
|
||||
├── opencode-version.ts # Semantic version comparison
|
||||
├── permission-compat.ts # Agent tool restriction enforcement
|
||||
├── system-directive.ts # Unified system message prefix & types
|
||||
├── session-utils.ts # Session cursor, orchestrator detection
|
||||
├── shell-env.ts # Cross-platform shell environment
|
||||
├── agent-variant.ts # Agent variant from config
|
||||
├── zip-extractor.ts # Binary/Resource ZIP extraction
|
||||
├── deep-merge.ts # Recursive object merging (proto-pollution safe, MAX_DEPTH=50)
|
||||
├── case-insensitive.ts # Case-insensitive object lookups
|
||||
├── session-cursor.ts # Session message cursor tracking
|
||||
├── command-executor.ts # Shell command execution (225 lines)
|
||||
└── index.ts # Barrel export for all utilities
|
||||
```
|
||||
|
||||
## WHEN TO USE
|
||||
## MOST IMPORTED
|
||||
| Utility | Users | Purpose |
|
||||
|---------|-------|---------|
|
||||
| logger.ts | 16+ | Background task visibility |
|
||||
| system-directive.ts | 8+ | Message filtering |
|
||||
| opencode-config-dir.ts | 8+ | Path resolution |
|
||||
| permission-compat.ts | 6+ | Tool restrictions |
|
||||
|
||||
## WHEN TO USE
|
||||
| Task | Utility |
|
||||
|------|---------|
|
||||
| Debug logging | `log(message, data)` |
|
||||
| Limit context | `dynamicTruncate(ctx, sessionId, output)` |
|
||||
| Parse frontmatter | `parseFrontmatter(content)` |
|
||||
| Load JSONC | `parseJsonc(text)` or `readJsoncFile(path)` |
|
||||
| Restrict tools | `createAgentToolAllowlist(tools)` |
|
||||
| Resolve paths | `getOpenCodeConfigDir()` |
|
||||
| Compare versions | `isOpenCodeVersionAtLeast("1.1.0")` |
|
||||
| Resolve model | `resolveModelWithFallback()` |
|
||||
| Agent display name | `getAgentDisplayName(agentName)` |
|
||||
| Path Resolution | `getOpenCodeConfigDir()`, `getDataPath()` |
|
||||
| Token Truncation | `dynamicTruncate(ctx, sessionId, output)` |
|
||||
| Config Parsing | `readJsoncFile<T>(path)`, `parseJsonc(text)` |
|
||||
| Model Resolution | `resolveModelWithFallback(client, reqs, override)` |
|
||||
| Version Gating | `isOpenCodeVersionAtLeast(version)` |
|
||||
| YAML Metadata | `parseFrontmatter(content)` |
|
||||
| Tool Security | `createAgentToolAllowlist(tools)` |
|
||||
| System Messages | `createSystemDirective(type)`, `isSystemDirective(msg)` |
|
||||
| Deep Merge | `deepMerge(target, source)` |
|
||||
|
||||
## PATTERNS
|
||||
## KEY PATTERNS
|
||||
|
||||
**3-Step Resolution** (Override → Fallback → Default):
|
||||
```typescript
|
||||
// Token-aware truncation
|
||||
const { result } = await dynamicTruncate(ctx, sessionID, buffer)
|
||||
const model = resolveModelWithFallback({
|
||||
userModel: config.agents.sisyphus.model,
|
||||
fallbackChain: AGENT_MODEL_REQUIREMENTS.sisyphus.fallbackChain,
|
||||
availableModels: fetchedModels,
|
||||
})
|
||||
```
|
||||
|
||||
// JSONC config
|
||||
const settings = readJsoncFile<Settings>(configPath)
|
||||
|
||||
// Version-gated
|
||||
if (isOpenCodeVersionAtLeast("1.1.0")) { /* ... */ }
|
||||
|
||||
// Model resolution
|
||||
const model = await resolveModelWithFallback(client, requirements, override)
|
||||
**System Directive Filtering**:
|
||||
```typescript
|
||||
if (isSystemDirective(message)) return // Skip system-generated
|
||||
const directive = createSystemDirective("TODO CONTINUATION")
|
||||
```
|
||||
|
||||
## ANTI-PATTERNS
|
||||
|
||||
- **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`
|
||||
- **Raw JSON.parse**: Use `jsonc-parser.ts` for comment support
|
||||
- **Hardcoded Paths**: Use `*-config-dir.ts` or `data-path.ts`
|
||||
- **console.log**: Use `logger.ts` for background task visibility
|
||||
- **Unbounded Output**: Use `dynamic-truncator.ts` to prevent overflow
|
||||
- **Manual Version Check**: Use `opencode-version.ts` for semver safety
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
tools/
|
||||
├── [tool-name]/
|
||||
│ ├── index.ts # Barrel export
|
||||
│ ├── tools.ts # ToolDefinition
|
||||
│ ├── tools.ts # ToolDefinition or factory
|
||||
│ ├── types.ts # Zod schemas
|
||||
│ └── constants.ts # Fixed values
|
||||
├── lsp/ # 6 tools: definition, references, symbols, diagnostics, rename
|
||||
├── lsp/ # 6 tools: definition, references, symbols, diagnostics, rename (client.ts 596 lines)
|
||||
├── ast-grep/ # 2 tools: search, replace (25 languages)
|
||||
├── delegate-task/ # Category-based routing (1039 lines)
|
||||
├── delegate-task/ # Category-based routing (1070 lines, 302 nesting levels)
|
||||
├── session-manager/ # 4 tools: list, read, search, info
|
||||
├── grep/ # Custom grep with timeout
|
||||
├── glob/ # 60s timeout, 100 file limit
|
||||
@@ -30,32 +30,46 @@ tools/
|
||||
|
||||
## TOOL CATEGORIES
|
||||
|
||||
| Category | Tools | Purpose |
|
||||
| Category | Tools | Pattern |
|
||||
|----------|-------|---------|
|
||||
| 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 | Direct |
|
||||
| Search | ast_grep_search, ast_grep_replace, grep, glob | Direct |
|
||||
| Session | session_list, session_read, session_search, session_info | Direct |
|
||||
| Agent | delegate_task, call_omo_agent | Factory |
|
||||
| Background | background_output, background_cancel | Factory |
|
||||
| System | interactive_bash, look_at | Mixed |
|
||||
| Skill | skill, skill_mcp, slashcommand | Factory |
|
||||
|
||||
## HOW TO ADD
|
||||
|
||||
1. Create `src/tools/[name]/` with standard files
|
||||
2. Use `tool()` from `@opencode-ai/plugin/tool`
|
||||
3. Export from `src/tools/index.ts`
|
||||
4. Add to `builtinTools` object
|
||||
4. Static tools → `builtinTools`, Factory → separate export
|
||||
|
||||
## LSP SPECIFICS
|
||||
## TOOL PATTERNS
|
||||
|
||||
- **Client**: `client.ts` manages stdio, JSON-RPC (596 lines)
|
||||
- **Singleton**: `LSPServerManager` with ref counting
|
||||
- **Capabilities**: definition, references, symbols, diagnostics, rename
|
||||
**Direct ToolDefinition**:
|
||||
```typescript
|
||||
export const grep: ToolDefinition = tool({
|
||||
description: "...",
|
||||
args: { pattern: tool.schema.string() },
|
||||
execute: async (args) => result,
|
||||
})
|
||||
```
|
||||
|
||||
## AST-GREP SPECIFICS
|
||||
**Factory Function** (context-dependent):
|
||||
```typescript
|
||||
export function createDelegateTask(ctx, manager): ToolDefinition {
|
||||
return tool({ execute: async (args) => { /* uses ctx */ } })
|
||||
}
|
||||
```
|
||||
|
||||
- **Engine**: `@ast-grep/napi` for 25+ languages
|
||||
- **Patterns**: `$VAR` (single), `$$$` (multiple)
|
||||
## NAMING
|
||||
|
||||
- **Tool names**: snake_case (`lsp_goto_definition`)
|
||||
- **Functions**: camelCase (`createDelegateTask`)
|
||||
- **Directories**: kebab-case (`delegate-task/`)
|
||||
|
||||
## ANTI-PATTERNS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user