docs(agents): refresh hierarchical AGENTS.md with team-mode coverage
Update root + 43 directory-level AGENTS.md files to reflect current state: - Root AGENTS.md rewritten with accurate counts (1967 TS files, 1304 source + 663 test, 278k LOC, 120 barrel index.ts), 7-step init flow, 5-tier hook composition, and full Team Mode section (12 team_* tools, eligibility, storage layout, config gate) - src/AGENTS.md adds team-mode init step, current per-subdir file/LOC table - src/tools/AGENTS.md documents conditional gates (team-mode +12, task system +4, hashline +1, interactive_bash +1, look_at +1) with always-on baseline of 20 - src/hooks/AGENTS.md splits into 5 tiers + 4 conditional team-mode hooks - src/features/team-mode/AGENTS.md surfaces 12 tools, eligible agents, spawn-race-safe invariants, and integration points - src/features/builtin-skills/AGENTS.md tracks 10 skills incl. team-mode - src/agents/AGENTS.md, src/plugin/AGENTS.md, src/config/AGENTS.md updated for team-mode awareness, accurate counts, and current schema field list - All other AGENTS.md files refreshed to 2026-05-08 generation date
This commit is contained in:
@@ -1,32 +1,44 @@
|
||||
# oh-my-opencode — OpenCode Plugin
|
||||
|
||||
**Generated:** 2026-04-18 | **Commit:** 2892ca4a | **Branch:** dev
|
||||
**Generated:** 2026-05-08 | **Commit:** cd31d2a1a | **Branch:** dev
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
OpenCode plugin (npm: `oh-my-opencode`, dual-published as `oh-my-openagent` during transition) extending Claude Code with 11 agents, 52 lifecycle hooks, 26 tools, 3-tier MCP system (built-in + .mcp.json + skill-embedded), Hashline LINE#ID edit tool, IntentGate classifier, and Claude Code compatibility. 1766 TypeScript source files, 377k LOC, 104 barrel index.ts files. Entry: `src/index.ts` → 5-step init (loadConfig → createManagers → createTools → createHooks → createPluginInterface).
|
||||
OpenCode plugin (npm: `oh-my-opencode`, dual-published as `oh-my-openagent` during the rename transition) extending OpenCode with 11 agents, ~50 lifecycle hooks across 57 dirs, 20–39 tools (gated by config flags including team-mode), 3-tier MCP system (built-in + .mcp.json + skill-embedded), Hashline LINE#ID edit tool, IntentGate keyword detector, Team Mode (parallel multi-agent coordination, OFF by default), and Claude Code compatibility. **1967 TypeScript files (1304 source + 663 test), 278k LOC, 120 barrel `index.ts` files.** Entry: `src/index.ts` → 7-step init.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
oh-my-opencode/
|
||||
├── src/
|
||||
│ ├── index.ts # Plugin entry: default export `pluginModule`, shape `{ id, server }`
|
||||
│ ├── index.ts # Plugin entry; default export `pluginModule` = `{ id, server }`
|
||||
│ ├── plugin-config.ts # JSONC multi-level config: user → project → defaults (Zod v4)
|
||||
│ ├── plugin-interface.ts # 10 OpenCode hook handlers
|
||||
│ ├── create-managers.ts # 4 managers (Tmux, Background, SkillMcp, ConfigHandler)
|
||||
│ ├── create-tools.ts # ToolRegistry composition
|
||||
│ ├── create-hooks.ts # 5-tier hook composition
|
||||
│ ├── agents/ # 11 agents (Sisyphus, Hephaestus, Oracle, Librarian, Explore, Atlas, Prometheus, Metis, Momus, Multimodal-Looker, Sisyphus-Junior)
|
||||
│ ├── hooks/ # 52 lifecycle hooks across dedicated modules and standalone files
|
||||
│ ├── tools/ # 26 tools across 16 directories (includes Hashline edit with LINE#ID content hashing)
|
||||
│ ├── features/ # 20 feature modules (background-agent, skill-loader, tmux, MCP-OAuth, skill-mcp-manager, team-mode, etc.)
|
||||
│ ├── shared/ # 170+ utility files (barrel-exported, logger → /tmp/oh-my-opencode.log)
|
||||
│ ├── config/ # Zod v4 schema system (32 files)
|
||||
│ ├── cli/ # CLI: install, run, doctor, mcp-oauth (Commander.js)
|
||||
│ ├── hooks/ # ~50 lifecycle hooks across 57 dirs
|
||||
│ ├── tools/ # 16 tool dirs; produces 20–39 tools (config-gated)
|
||||
│ ├── features/ # 20 feature modules (incl. team-mode, background-agent, skill-mcp-manager, openclaw, etc.)
|
||||
│ ├── shared/ # 258 utility files; logger → /tmp/oh-my-opencode.log
|
||||
│ ├── config/ # Zod v4 schema system (32 schema files)
|
||||
│ ├── cli/ # CLI: install, run, doctor, mcp-oauth, refresh-model-capabilities, get-local-version
|
||||
│ ├── mcp/ # 3 built-in remote MCPs (websearch, context7, grep_app)
|
||||
│ ├── plugin/ # 10 OpenCode hook handlers + 52 hook composition
|
||||
│ ├── plugin/ # 10 OpenCode hook handlers + 5-tier hook composition
|
||||
│ ├── plugin-handlers/ # 6-phase config loading pipeline
|
||||
│ └── openclaw/ # Bidirectional external integration (Discord/Telegram/webhook/command)
|
||||
├── packages/ # 11 platform-specific compiled binaries (darwin/linux/windows, AVX2 + baseline variants)
|
||||
│ ├── openclaw/ # Bidirectional external integration (Discord/Telegram/HTTP/shell + reply listener daemon)
|
||||
│ └── testing/ # Test utilities
|
||||
├── packages/ # 11 platform-specific compiled binary packages (darwin/linux/windows, AVX2 + baseline)
|
||||
├── bin/ # Platform-detection JS shim (oh-my-opencode + oh-my-openagent)
|
||||
├── script/ # Build/publish automation (singular, not scripts/)
|
||||
├── .sisyphus/ # AI agent workspace (rules, plans, tasks, notepads)
|
||||
├── docs/ # User-facing docs (guide/, reference/, examples/, legal/, manifesto.md, superpowers/)
|
||||
├── assets/ # oh-my-opencode.schema.json (auto-generated from Zod)
|
||||
├── signatures/ # CLA signature registry (cla.json)
|
||||
├── postinstall.mjs # Verifies platform binary + OpenCode version
|
||||
├── test-setup.ts # Bun test preload (resets state between tests)
|
||||
├── bun-test.d.ts # Custom bun:test type augmentations
|
||||
├── .sisyphus/ # AI agent workspace (run-continuation/, plans/, tasks/, notepads/)
|
||||
└── .local-ignore/ # Dev-only test fixtures + PR worktrees
|
||||
```
|
||||
|
||||
@@ -34,140 +46,193 @@ oh-my-opencode/
|
||||
|
||||
```
|
||||
pluginModule.server(input, options)
|
||||
├─→ loadPluginConfig() # JSONC parse → project/user merge → Zod validate → migrate
|
||||
├─→ createManagers() # TmuxSessionManager, BackgroundManager, SkillMcpManager, ConfigHandler
|
||||
├─→ createTools() # SkillContext + AvailableCategories + ToolRegistry (26 tools)
|
||||
├─→ createHooks() # 3-tier: Core(43) + Continuation(7) + Skill(2) = 52 hooks
|
||||
└─→ createPluginInterface() # 10 OpenCode hook handlers → PluginInterface
|
||||
├─→ installAgentSortShim() # patches Array.prototype.{toSorted,sort} for canonical agent ordering
|
||||
├─→ initConfigContext() # opencode-vs-openagent layout flag
|
||||
├─→ detectExternalSkillPlugin() # warn on conflicts
|
||||
├─→ injectServerAuthIntoClient() # auth headers into shared SDK client
|
||||
├─→ loadPluginConfig() # JSONC parse → user/project merge → Zod validate → migrate
|
||||
├─→ initializeOpenClaw() # if openclaw config present
|
||||
├─→ checkTeamModeDependencies() # if team_mode.enabled
|
||||
├─→ createManagers() # TmuxSessionManager, BackgroundManager, SkillMcpManager, ConfigHandler
|
||||
├─→ createTools() # SkillContext + AvailableCategories + ToolRegistry
|
||||
├─→ createHooks() # 5-tier: Session + ToolGuard + Transform + Continuation + Skill
|
||||
└─→ createPluginInterface() # 10 OpenCode hook handlers → PluginInterface
|
||||
```
|
||||
|
||||
## 10 OPENCODE HOOK HANDLERS
|
||||
|
||||
| Handler | Purpose |
|
||||
|---------|---------|
|
||||
| `config` | 6-phase: provider → plugin-components → agents → tools → MCPs → commands |
|
||||
| `tool` | 26 registered tools |
|
||||
| `chat.message` | First-message variant, session setup, keyword detection (ultrawork/search/analyze) |
|
||||
| `chat.params` | Anthropic effort level, think mode, runtime fallback override |
|
||||
| `chat.headers` | Copilot x-initiator header injection |
|
||||
| `event` | Session lifecycle (created, deleted, idle, error), openclaw dispatch, runtime fallback |
|
||||
| `tool.execute.before` | Pre-tool hooks (file guard, label truncator, rules injector, prometheus md-only) |
|
||||
| `tool.execute.after` | Post-tool hooks (output truncation, comment checker, hashline read enhancer) |
|
||||
| `experimental.chat.messages.transform` | Context injection, thinking block validation, tool pair validation |
|
||||
| `experimental.session.compacting` | Context + todo preservation during compaction |
|
||||
| Handler | OpenCode Hook | Purpose |
|
||||
|---------|---------------|---------|
|
||||
| `config` | `config` | 6-phase pipeline: provider → plugin-components → agents → tools → MCPs → commands |
|
||||
| `tool` | `tool` | 20–39 registered tools (config-gated: team-mode +12, task system +4, hashline +1, interactive_bash +1, look_at +1) |
|
||||
| `chat.message` | `chat.message` | First-message variant, session setup, keyword detection (ultrawork/search/analyze/team) |
|
||||
| `chat.params` | `chat.params` | Anthropic effort, think mode, runtime fallback override |
|
||||
| `chat.headers` | `chat.headers` | Copilot `x-initiator` header injection |
|
||||
| `event` | `event` | Session lifecycle (created/deleted/idle/error), openclaw dispatch, runtime fallback |
|
||||
| `tool.execute.before` | `tool.execute.before` | Pre-tool guards (write-existing-guard, label-truncator, rules-injector, prometheus-md-only, …) |
|
||||
| `tool.execute.after` | `tool.execute.after` | Post-tool hooks (output truncator, comment-checker, hashline read-enhancer, json-error-recovery, …) |
|
||||
| `experimental.chat.messages.transform` | `experimental.chat.messages.transform` | Context injection, thinking-block validation, tool-pair validation, keyword detection |
|
||||
| `experimental.session.compacting` | `experimental.session.compacting` | Context + todo preservation across compaction |
|
||||
|
||||
## TOOL CATALOG (config-gated)
|
||||
|
||||
**Always on (20):** `lsp_goto_definition`, `lsp_find_references`, `lsp_symbols`, `lsp_diagnostics`, `lsp_prepare_rename`, `lsp_rename`, `grep`, `glob`, `ast_grep_search`, `ast_grep_replace`, `session_list`, `session_read`, `session_search`, `session_info`, `background_output`, `background_cancel`, `call_omo_agent`, `task` (delegate), `skill`, `skill_mcp`.
|
||||
|
||||
**Conditional:** `look_at` (+1, multimodal-looker not disabled), `interactive_bash` (+1, tmux enabled), `task_create`/`task_get`/`task_list`/`task_update` (+4, `experimental.task_system`), `edit` (+1, `hashline_edit`), `team_create`/`team_delete`/`team_shutdown_request`/`team_approve_shutdown`/`team_reject_shutdown`/`team_send_message`/`team_task_create`/`team_task_list`/`team_task_update`/`team_task_get`/`team_status`/`team_list` (+12, `team_mode.enabled`).
|
||||
|
||||
## TEAM MODE
|
||||
|
||||
OFF by default. Parallel multi-agent coordination, modeled after Claude Code Agent Teams. Enable via `team_mode.enabled` in `.opencode/oh-my-opencode.jsonc` or user config; restart OpenCode after change.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"team_mode": {
|
||||
"enabled": true,
|
||||
"max_parallel_members": 4,
|
||||
"max_members": 8,
|
||||
"tmux_visualization": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Teams live as directories under `~/.omo/teams/{name}/config.json` (user) or `<project>/.omo/teams/{name}/config.json` (project; project beats user on collisions). Members declared as `kind: "subagent_type"` (direct agent) or `kind: "category"` (routed through `sisyphus-junior`).
|
||||
|
||||
**Eligible members only:** sisyphus, atlas, sisyphus-junior, hephaestus. Read-only / orchestration agents (oracle, librarian, explore, multimodal-looker, metis, momus, prometheus) are rejected at parse time — use `task` (delegate) for those.
|
||||
|
||||
**Storage layout** (`~/.omo/teams/{name}/`): `config.json` (spec), `state.json` (runtime), `mailbox/` (messages), `tasklist.jsonl` (tasks), `worktrees/` (per-member git worktrees).
|
||||
|
||||
**Implementation:** [`src/features/team-mode/`](file:///Users/yeongyu/local-workspaces/omo/src/features/team-mode/AGENTS.md). User docs: [`docs/guide/team-mode.md`](file:///Users/yeongyu/local-workspaces/omo/docs/guide/team-mode.md).
|
||||
|
||||
## MULTI-LEVEL CONFIG
|
||||
|
||||
```
|
||||
Walked configs (closer wins): <pwd up to $HOME>/.opencode/oh-my-openagent.json[c] (legacy: oh-my-opencode.json[c])
|
||||
↓ merged onto
|
||||
User config: ~/.config/opencode/oh-my-openagent.json[c] (Windows: %APPDATA%\opencode\)
|
||||
↓ falls back to
|
||||
Defaults (Zod safeParse fills omitted fields)
|
||||
```
|
||||
|
||||
- `agents`, `categories`, `claude_code`: deep merged recursively (prototype-pollution safe)
|
||||
- `disabled_*` arrays: Set union (concatenated + deduplicated)
|
||||
- All other fields: override replaces base value
|
||||
- `mcp_env_allowlist`: **user-only** for security; walked configs cannot extend it
|
||||
- `migrateConfigFile()` rewrites legacy keys (idempotent via `_migrations` tracking + timestamped backups)
|
||||
|
||||
Schema autocomplete: `"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json"`
|
||||
|
||||
## THREE-TIER MCP SYSTEM
|
||||
|
||||
| Tier | Source | Loader | Mechanism |
|
||||
|------|--------|--------|-----------|
|
||||
| 1. Built-in | `src/mcp/` | `createBuiltinMcps()` | 3 remote HTTP: websearch (Exa/Tavily), context7, grep_app |
|
||||
| 2. Claude Code | `.mcp.json` (project + user) | `claude-code-mcp-loader` | `${VAR}` env expansion (allowlist via `mcp_env_allowlist`) |
|
||||
| 3. Skill-embedded | SKILL.md YAML frontmatter | `SkillMcpManager` (per-session) | stdio + HTTP, OAuth 2.0 + PKCE + DCR step-up |
|
||||
|
||||
## WHERE TO LOOK
|
||||
|
||||
| Task | Location | Notes |
|
||||
|------|----------|-------|
|
||||
| Add new agent | `src/agents/` + `src/agents/builtin-agents/` | Follow createXXXAgent factory pattern |
|
||||
| Add new hook | `src/hooks/{name}/` + register in `src/plugin/hooks/create-*-hooks.ts` | Match event type to tier |
|
||||
| Add new tool | `src/tools/{name}/` + register in `src/plugin/tool-registry.ts` | Follow createXXXTool factory |
|
||||
| Add new feature module | `src/features/{name}/` | Standalone module, wire in plugin/ |
|
||||
| Add new MCP | `src/mcp/` + register in `createBuiltinMcps()` | Remote HTTP only (tier 1 of 3) |
|
||||
| Add new skill | `src/features/builtin-skills/skills/` | Implement BuiltinSkill interface |
|
||||
| Add new command | `src/features/builtin-commands/` | Template in templates/ |
|
||||
| Add new CLI command | `src/cli/cli-program.ts` | Commander.js subcommand |
|
||||
| Add new doctor check | `src/cli/doctor/checks/` | Register in checks/index.ts |
|
||||
| Modify config schema | `src/config/schema/` + update root schema | Zod v4, add to OhMyOpenCodeConfigSchema |
|
||||
| Add new category | `src/tools/delegate-task/constants.ts` | DEFAULT_CATEGORIES + CATEGORY_MODEL_REQUIREMENTS |
|
||||
| Debug provider errors | `src/hooks/runtime-fallback/` | Reactive error recovery (distinct from model-fallback) |
|
||||
| External notifications | `src/openclaw/` | Bidirectional Discord/Telegram/webhook integration |
|
||||
| Skill-embedded MCP | `src/features/skill-mcp-manager/` | Tier 3 MCPs (stdio + HTTP, per-session) |
|
||||
| Team mode | `src/features/team-mode/` | Parallel multi-agent coordination (OFF by default) |
|
||||
| Add new agent | `src/agents/` + `src/agents/builtin-agents/` | `createXXXAgent` factory + `mode: "primary" \| "subagent" \| "all"` |
|
||||
| Add new hook | `src/hooks/{name}/` + register in `src/plugin/hooks/create-*-hooks.ts` | Pick the right tier (Session/ToolGuard/Transform/Continuation/Skill) |
|
||||
| Add new tool | `src/tools/{name}/` + register in `src/plugin/tool-registry.ts` | Factory `createXXXTool` (most) or direct `ToolDefinition` (LSP, interactive_bash) |
|
||||
| Add new feature module | `src/features/{name}/` | Standalone module wired into `plugin/` layer |
|
||||
| Add new MCP (tier 1) | `src/mcp/` + register in `createBuiltinMcps()` | Remote HTTP only |
|
||||
| Add new built-in skill | `src/features/builtin-skills/skills/{name}.ts` + register in `skills.ts` | Implement `BuiltinSkill` interface |
|
||||
| Add new command | `src/features/builtin-commands/` | Templates in `templates/` |
|
||||
| Add new CLI subcommand | `src/cli/cli-program.ts` | Commander.js subcommand |
|
||||
| Add new doctor check | `src/cli/doctor/checks/` | Register in `checks/index.ts` |
|
||||
| Modify config schema | `src/config/schema/` + add to `OhMyOpenCodeConfigSchema` | Zod v4; auto-included in `assets/oh-my-opencode.schema.json` after `bun run build:schema` |
|
||||
| Add new category | `src/tools/delegate-task/constants.ts` | `DEFAULT_CATEGORIES` + `CATEGORY_MODEL_REQUIREMENTS` |
|
||||
| Add new team-mode tool | `src/features/team-mode/tools/` + register in `src/plugin/tool-registry.ts` `teamModeToolsRecord` | Gated on `team_mode.enabled` |
|
||||
| Reactive provider error recovery | `src/hooks/runtime-fallback/` | Distinct from `model-fallback` (proactive, chat.params) |
|
||||
| External notifications | `src/openclaw/` | Bidirectional: outbound (event → HTTP/shell), inbound (Discord/Telegram daemon → tmux send-keys) |
|
||||
| Skill-embedded MCP | `src/features/skill-mcp-manager/` | Tier-3 MCPs (per-session, stdio + HTTP) |
|
||||
|
||||
## MULTI-LEVEL CONFIG
|
||||
## ARCHITECTURE INVARIANTS
|
||||
|
||||
```
|
||||
Project (.opencode/oh-my-opencode.jsonc) → User (~/.config/opencode/oh-my-opencode.jsonc) → Defaults
|
||||
```
|
||||
|
||||
- `agents`, `categories`, `claude_code`: deep merged recursively (prototype-pollution-safe)
|
||||
- `disabled_*` arrays: Set union (concatenated + deduplicated)
|
||||
- All other fields: override replaces base value
|
||||
- Zod `safeParse()` fills defaults for omitted fields; partial parsing as fallback
|
||||
- `migrateConfigFile()` transforms legacy keys automatically (idempotent via `_migrations` tracking)
|
||||
|
||||
Fields: agents (14 overridable, 21 fields each), categories (8 built-in + custom), disabled_* arrays (agents, hooks, mcps, skills, commands, tools), 19 feature-specific configs.
|
||||
|
||||
## THREE-TIER MCP SYSTEM
|
||||
|
||||
| Tier | Source | Mechanism |
|
||||
|------|--------|-----------|
|
||||
| Built-in | `src/mcp/` | 3 remote HTTP: websearch (Exa/Tavily), context7, grep_app |
|
||||
| Claude Code | `.mcp.json` | `${VAR}` env expansion via claude-code-mcp-loader |
|
||||
| Skill-embedded | SKILL.md YAML | Managed by SkillMcpManager (stdio + HTTP) |
|
||||
- **Canonical agent order:** Sisyphus → Hephaestus → Prometheus → Atlas. Enforced by `installAgentSortShim()` (patches `Array.prototype.toSorted`/`.sort` narrowly when the array contains ≥2 canonical core agents). See [`src/plugin-handlers/AGENTS.md`](file:///Users/yeongyu/local-workspaces/omo/src/plugin-handlers/AGENTS.md) for the full history of why this exists.
|
||||
- **Hashline edit + read pairing:** Every `Read` tool output is tagged with `LINE#ID` content hashes; `hashline_edit` validates the hash before applying. Stale hash → reject.
|
||||
- **5-tier hook composition:** Session (24) + ToolGuard (14) + Transform (5) + Continuation (7) + Skill (2). Composed by `createCoreHooks()` + `createContinuationHooks()` + `createSkillHooks()`.
|
||||
- **Per-session MCP isolation:** Tier-3 MCP clients keyed by `${sessionID}:${skillName}:${serverName}` so the same skill in two sessions does not share state.
|
||||
- **Two fallback systems:** `model-fallback` (proactive, chat.params) vs `runtime-fallback` (reactive, session.error). They operate independently — no direct integration.
|
||||
- **OpenClaw bidirectional:** Outbound dispatchers fire on session events; inbound daemon polls Discord/Telegram and `send-keys` replies into the tracked tmux pane.
|
||||
|
||||
## CONVENTIONS
|
||||
|
||||
- **Runtime**: Bun only (1.3.11 in CI) -- never use npm/yarn
|
||||
- **TypeScript**: strict mode, ESNext, bundler moduleResolution, `bun-types` (never `@types/node`)
|
||||
- **Test pattern**: Bun test (`bun:test`), co-located `*.test.ts`, given/when/then style (nested describe with `#given`/`#when`/`#then` prefixes or inline `// given` / `// when` / `// then` comments)
|
||||
- **CI test split**: `script/run-ci-tests.ts` auto-detects `mock.module()` usage, isolates those tests in separate processes
|
||||
- **Factory pattern**: `createXXX()` for all tools, hooks, agents
|
||||
- **Hook tiers**: Session (24) → Tool-Guard (14) → Transform (5) → Continuation (7) → Skill (2)
|
||||
- **Agent modes**: `primary` (respects UI model) vs `subagent` (own fallback chain) vs `all`
|
||||
- **Model resolution**: 4-step: override → category-default → provider-fallback → system-default
|
||||
- **Config format**: JSONC with comments, Zod v4 validation, snake_case keys
|
||||
- **File naming**: kebab-case for all files/directories
|
||||
- **Module structure**: index.ts barrel exports, no catch-all files (utils.ts, helpers.ts banned), 200 LOC soft limit
|
||||
- **Imports**: relative within module, barrel imports across modules (`import { log } from "./shared"`)
|
||||
- **No path aliases**: no `@/` -- relative imports only
|
||||
- **Dual package**: `oh-my-opencode` + `oh-my-openagent` published simultaneously (transition period)
|
||||
- **Runtime:** Bun only (1.3.11 in CI). Never npm/yarn/pnpm.
|
||||
- **TypeScript:** strict mode, ESNext, bundler moduleResolution, `bun-types` (never `@types/node`).
|
||||
- **Tests:** Bun test (`bun:test`), co-located `*.test.ts`, given/when/then style — nested `describe` with `#given`/`#when`/`#then` prefixes, or inline `// given` / `// when` / `// then` comments. Never Arrange-Act-Assert comments.
|
||||
- **CI test split:** `script/run-ci-tests.ts` auto-detects `mock.module()` and isolates those tests in separate processes.
|
||||
- **Test setup:** `test-setup.ts` preloaded via `bunfig.toml` resets session/cache state between tests.
|
||||
- **Factory pattern:** `createXXX()` for all tools, hooks, agents.
|
||||
- **File naming:** kebab-case for files and directories.
|
||||
- **Module structure:** `index.ts` barrel exports, **no catch-all files** (`utils.ts`, `helpers.ts`, `service.ts` banned), 200 LOC soft limit per file.
|
||||
- **Imports:** relative within a module, barrel imports across modules (`import { log } from "./shared"`). **No path aliases** — never `@/`.
|
||||
- **Config format:** JSONC with comments + trailing commas, Zod v4 validation, snake_case keys.
|
||||
- **Dual package:** `oh-my-opencode` + `oh-my-openagent` published simultaneously during the rename transition.
|
||||
- **Comments:** AI slop comment patterns blocked by `comment-checker` hook (binary: `@code-yeongyu/comment-checker`). Use `// @allow` to bypass single line, `// comment-checker-disable-file` at file top to bypass file. Sparingly.
|
||||
|
||||
## ANTI-PATTERNS
|
||||
## ANTI-PATTERNS (BLOCKING)
|
||||
|
||||
- Never use `as any`, `@ts-ignore`, `@ts-expect-error`
|
||||
- Never suppress lint/type errors
|
||||
- Never add emojis to code/comments unless user explicitly asks
|
||||
- Never commit unless explicitly requested
|
||||
- Never run `bun publish` directly -- use GitHub Actions
|
||||
- Never modify `package.json` version locally
|
||||
- Test: given/when/then -- never use Arrange-Act-Assert comments
|
||||
- Comments: avoid AI-generated comment patterns (enforced by comment-checker hook)
|
||||
- Never create catch-all files (`utils.ts`, `helpers.ts`, `service.ts`)
|
||||
- Empty catch blocks `catch(e) {}` -- always handle errors
|
||||
- Never use em dashes, en dashes, or AI filler phrases in generated content
|
||||
- index.ts is entry point ONLY -- never dump business logic there
|
||||
- Never `as any`, `@ts-ignore`, `@ts-expect-error`.
|
||||
- Never suppress lint/type errors.
|
||||
- Never add emojis to code/comments unless user explicitly asks.
|
||||
- Never commit unless explicitly requested.
|
||||
- Never run `bun publish` directly — use the GitHub Actions workflow.
|
||||
- Never modify `package.json` `version` locally — handled by publish workflow.
|
||||
- Never write to existing files without reading them first (`write-existing-file-guard`).
|
||||
- Never use `background_cancel(all=true)` — cancel by `taskId` individually.
|
||||
- Never delete a failing test to make a build green. Fix the code.
|
||||
- Never em dashes / en dashes / AI filler ("simply", "obviously", "clearly", "moreover", "furthermore") in generated content.
|
||||
- Never create catch-all files (`utils.ts`, `helpers.ts`, `service.ts`).
|
||||
- Never empty catch blocks `catch(e) {}`.
|
||||
- Never test with Arrange-Act-Assert comments — use given/when/then.
|
||||
- Never dump business logic into `index.ts` — barrel exports only.
|
||||
- Prometheus may ONLY edit `.md` files (enforced by `prometheus-md-only` hook); FORBIDDEN paths: `src/`, `package.json`, config files.
|
||||
|
||||
## COMMANDS
|
||||
|
||||
```bash
|
||||
bun test # Bun test suite
|
||||
bun run build # Build plugin (ESM + declarations + schema)
|
||||
bun run build:all # Build + platform binaries
|
||||
bun run typecheck # tsc --noEmit
|
||||
bunx oh-my-opencode install # Interactive setup
|
||||
bunx oh-my-opencode doctor # Health diagnostics
|
||||
bunx oh-my-opencode run # Non-interactive session
|
||||
bun test # Bun test suite (auto-split mock-heavy tests via script/run-ci-tests.ts)
|
||||
bun run build # Build plugin (ESM bundle + .d.ts + cli bundle + schema generation)
|
||||
bun run build:all # Build + 11 platform binaries
|
||||
bun run build:schema # Regenerate assets/oh-my-opencode.schema.json
|
||||
bun run build:model-capabilities # Refresh shared/model-capabilities cache from models.dev
|
||||
bun run typecheck # tsc --noEmit
|
||||
bun run clean # rm -rf dist
|
||||
bunx oh-my-opencode install # Interactive setup wizard
|
||||
bunx oh-my-opencode doctor # Health diagnostics (4 categories: System / Config / Tools / Models)
|
||||
bunx oh-my-opencode run <message> # Non-interactive session (auto-completes when todos done + no bg tasks)
|
||||
bunx oh-my-opencode mcp-oauth login <server-url> # Tier-3 MCP OAuth (PKCE + DCR)
|
||||
```
|
||||
|
||||
## CI/CD
|
||||
|
||||
| Workflow | Trigger | Purpose |
|
||||
|----------|---------|---------|
|
||||
| ci.yml | push/PR to master/dev | Tests (split: mock-heavy isolated + batch), typecheck, build, schema auto-commit |
|
||||
| publish.yml | manual dispatch | Version bump, dual npm publish (oh-my-opencode + oh-my-openagent), platform binaries, GitHub release |
|
||||
| publish-platform.yml | called by publish | 11 platform binaries via bun compile (darwin/linux/windows) |
|
||||
| sisyphus-agent.yml | @mention / dispatch | AI agent handles issues/PRs |
|
||||
| refresh-model-capabilities.yml | weekly schedule / dispatch | Auto-refresh model capabilities from models.dev API |
|
||||
| cla.yml | issue_comment/PR | CLA assistant for contributors |
|
||||
| lint-workflows.yml | push to .github/ | actionlint + shellcheck on workflow files |
|
||||
| `ci.yml` | push/PR to master/dev | Tests (split: mock-heavy isolated + batch), typecheck, build, schema auto-commit |
|
||||
| `publish.yml` | manual dispatch | Version bump, dual npm publish (`oh-my-opencode` + `oh-my-openagent`), platform binaries, GitHub release |
|
||||
| `publish-platform.yml` | called by publish.yml | 11 platform binaries via `bun compile` (darwin/linux/windows) |
|
||||
| `sisyphus-agent.yml` | @mention or manual dispatch | AI agent handles issues/PRs |
|
||||
| `refresh-model-capabilities.yml` | weekly cron / dispatch | Refresh model capabilities from models.dev API |
|
||||
| `cla.yml` | issue_comment / PR | CLA assistant for contributors |
|
||||
| `lint-workflows.yml` | push to .github/ | actionlint + shellcheck on workflow files |
|
||||
|
||||
## NOTES
|
||||
|
||||
- Logger writes to `/tmp/oh-my-opencode.log` -- check there for debugging
|
||||
- Background tasks: 5 concurrent per model/provider (configurable, circuit breaker support)
|
||||
- Plugin load timeout: 10s for Claude Code plugins
|
||||
- Model fallback: per-agent chains in `shared/model-requirements.ts`, not a single global priority
|
||||
- Two fallback systems: `model-fallback` (proactive, chat.params) vs `runtime-fallback` (reactive, session.error)
|
||||
- Config migration: idempotent via `_migrations` tracking, creates timestamped backups before atomic writes
|
||||
- Build: bun build (ESM) + tsc --emitDeclarationOnly, externals: @ast-grep/napi
|
||||
- Test setup: `test-setup.ts` preloaded via bunfig.toml, resets session/cache state between tests
|
||||
- Test split: `script/run-ci-tests.ts` auto-isolates files using `mock.module()` (plus `src/openclaw/__tests__/reply-listener-discord.test.ts`)
|
||||
- 104 barrel export files (index.ts) establish module boundaries
|
||||
- Architecture rules enforced via `.sisyphus/rules/modular-code-enforcement.md`
|
||||
- Windows builds run on `windows-latest` runner (not cross-compiled) to avoid Bun segfaults
|
||||
- Platform binaries detect AVX2 + libc family at runtime, fallback to baseline if needed
|
||||
- Hashline edit: every Read output tagged with `LINE#ID` content hashes; edits reject on hash mismatch
|
||||
- IntentGate: classifies user intent (research/implementation/investigation/evaluation/fix) before routing
|
||||
- **Logger:** writes to `/tmp/oh-my-opencode.log` — check there for debugging.
|
||||
- **Background tasks:** 5 concurrent per `${providerID}/${modelID}` key by default (configurable via `background_task.modelConcurrency` / `providerConcurrency`); FIFO queue when slots full.
|
||||
- **Plugin load timeout:** 10s for Claude Code plugin discovery.
|
||||
- **Model fallback:** per-agent chains in `src/shared/model-requirements.ts`. **There is no single global priority.**
|
||||
- **Two fallback systems:** `model-fallback` (proactive, chat.params, hardcoded chains) vs `runtime-fallback` (reactive, session.error, configurable per-category/agent).
|
||||
- **Config migration:** idempotent via `_migrations` tracking, atomic writes with timestamped backups.
|
||||
- **Build:** `bun build` (ESM) + `tsc --emitDeclarationOnly`, externals: `@ast-grep/napi`, `zod`.
|
||||
- **CI test isolation:** `script/run-ci-tests.ts` auto-isolates files using `mock.module()` (plus `src/openclaw/__tests__/reply-listener-discord.test.ts`) — they run in separate processes.
|
||||
- **120 barrel `index.ts` files** establish module boundaries.
|
||||
- **Architecture rules** enforced via `.sisyphus/rules/modular-code-enforcement.md` (when present in workspace).
|
||||
- **Windows builds:** run on `windows-latest` (not cross-compiled) to avoid Bun segfaults.
|
||||
- **Platform binaries:** detect AVX2 + libc family at runtime, fallback to baseline if needed.
|
||||
- **IntentGate (`keyword-detector`):** classifies user intent (`ultrawork`/`ulw`, `search`, `analyze`, `team`) and injects mode-specific prompts.
|
||||
- **Hashline edit:** every `Read` output tagged with `LINE#ID` content hashes (chars from `ZPMQVRWSNKTXJBYH`); edits reject on hash mismatch.
|
||||
- **Docs:** see [`docs/guide/`](file:///Users/yeongyu/local-workspaces/omo/docs/guide/) for user-facing guides (overview, installation, orchestration, agent-model-matching, team-mode), [`docs/reference/`](file:///Users/yeongyu/local-workspaces/omo/docs/reference/) for CLI/configuration/features reference.
|
||||
|
||||
+78
-18
@@ -1,41 +1,101 @@
|
||||
# src/ — Plugin Source
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
Entry point `index.ts` orchestrates 5-step initialization: loadConfig → createManagers → createTools → createHooks → createPluginInterface.
|
||||
Entry `index.ts` orchestrates a 7-step initialization. Total: 1304 source files + 663 tests across the directories below. Cross-cutting helpers live in `shared/`; module boundaries are established by 120 barrel `index.ts` files.
|
||||
|
||||
## KEY FILES
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `index.ts` | Plugin entry, default-exports `pluginModule: PluginModule` with `{ id, server }` |
|
||||
| `plugin-config.ts` | JSONC parse, multi-level merge, Zod v4 validation |
|
||||
| `index.ts` | Plugin entry; default-exports `pluginModule: PluginModule` with `{ id, server }` |
|
||||
| `plugin-config.ts` | JSONC parse, multi-level merge (user + walked project), Zod v4 validation, migration |
|
||||
| `plugin-state.ts` | `createModelCacheState()` — model resolution cache shared across handlers |
|
||||
| `plugin-interface.ts` | 10 OpenCode hook handlers wired into `Hooks` |
|
||||
| `create-managers.ts` | TmuxSessionManager, BackgroundManager, SkillMcpManager, ConfigHandler |
|
||||
| `create-tools.ts` | SkillContext + AvailableCategories + ToolRegistry (26 tools) |
|
||||
| `create-hooks.ts` | 3-tier: Core(43) + Continuation(7) + Skill(2) = 52 hooks |
|
||||
| `plugin-interface.ts` | 10 OpenCode hook handlers: config, tool, chat.message, chat.params, chat.headers, event, tool.execute.before, tool.execute.after, experimental.chat.messages.transform, experimental.session.compacting |
|
||||
| `create-tools.ts` | SkillContext + AvailableCategories + ToolRegistry composition |
|
||||
| `create-hooks.ts` | 5-tier composition: `createCoreHooks() + createContinuationHooks() + createSkillHooks()` |
|
||||
| `create-runtime-tmux-config.ts` | `isTmuxIntegrationEnabled()` + `createRuntimeTmuxConfig()` |
|
||||
|
||||
## CONFIG LOADING
|
||||
## INITIALIZATION (7 STEPS)
|
||||
|
||||
```
|
||||
serverPlugin(input, options)
|
||||
1. installAgentSortShim() # patches Array.prototype.{toSorted,sort} for canonical agent ordering
|
||||
2. initConfigContext() # detects opencode-vs-openagent config layout
|
||||
3. detectExternalSkillPlugin() # warn if conflicting plugin loaded
|
||||
4. injectServerAuthIntoClient() # wire auth headers into shared SDK client
|
||||
5. loadPluginConfig() # walk project + user JSONC → Zod safeParse → migrate
|
||||
6. initializeOpenClaw() # if openclaw config present (start reply-listener daemon)
|
||||
6. checkTeamModeDependencies() # if team_mode.enabled (verify git, tmux, ensure ~/.omo/teams/)
|
||||
7. createManagers/Tools/Hooks/PluginInterface
|
||||
```
|
||||
|
||||
## CONFIG LOADING (Phase pipeline)
|
||||
|
||||
```
|
||||
loadPluginConfig(directory, ctx)
|
||||
1. User: ~/.config/opencode/oh-my-opencode.jsonc
|
||||
2. Project: .opencode/oh-my-opencode.jsonc
|
||||
3. mergeConfigs(user, project) → deepMerge for agents/categories, Set union for disabled_*
|
||||
1. User: ~/.config/opencode/oh-my-openagent.jsonc (legacy: oh-my-opencode.jsonc)
|
||||
2. Walked configs: <pwd up to $HOME>/.opencode/oh-my-openagent.jsonc
|
||||
3. mergeConfigs(user, walked)
|
||||
- agents/categories/claude_code: deepMerge (recursive, prototype-pollution safe)
|
||||
- disabled_*: Set union
|
||||
- mcp_env_allowlist: user-only (security)
|
||||
- others: override replaces
|
||||
4. Zod safeParse → defaults for omitted fields
|
||||
5. migrateConfigFile() → legacy key transformation
|
||||
5. migrateConfigFile() → idempotent via _migrations tracking + timestamped backups
|
||||
```
|
||||
|
||||
## HOOK COMPOSITION
|
||||
## HOOK COMPOSITION (5-tier)
|
||||
|
||||
```
|
||||
createHooks()
|
||||
├─→ createCoreHooks() # 43 hooks
|
||||
│ ├─ createSessionHooks() # 24: contextWindowMonitor, thinkMode, ralphLoop, modelFallback, runtimeFallback, noSisyphusGpt, noHephaestusNonGpt, anthropicEffort, intentGate, legacyPluginToast...
|
||||
│ ├─ createToolGuardHooks() # 14: commentChecker, rulesInjector, writeExistingFileGuard, jsonErrorRecovery, hashlineReadEnhancer, bashFileReadGuard, readImageResizer, todoDescriptionOverride, webfetchRedirectGuard...
|
||||
│ └─ createTransformHooks() # 5: claudeCodeHooks, keywordDetector, contextInjector, thinkingBlockValidator, toolPairValidator
|
||||
├─→ createContinuationHooks() # 7: todoContinuationEnforcer, atlas, stopContinuationGuard, compactionContextInjector...
|
||||
├─→ createCoreHooks()
|
||||
│ ├─ createSessionHooks() # 24: contextWindowMonitor, thinkMode, ralphLoop, modelFallback,
|
||||
│ │ runtimeFallback, anthropicEffort, anthropicContextWindowLimitRecovery,
|
||||
│ │ autoUpdateChecker, agentUsageReminder, nonInteractiveEnv,
|
||||
│ │ interactiveBashSession, editErrorRecovery, delegateTaskRetry,
|
||||
│ │ startWork, prometheusMdOnly, sisyphusJuniorNotepad,
|
||||
│ │ questionLabelTruncator, taskResumeInfo, noSisyphusGpt,
|
||||
│ │ noHephaestusNonGpt, legacyPluginToast, sessionRecovery,
|
||||
│ │ sessionNotification, preemptiveCompaction
|
||||
│ ├─ createToolGuardHooks() # 14: commentChecker, toolOutputTruncator, directoryAgentsInjector,
|
||||
│ │ directoryReadmeInjector, emptyTaskResponseDetector, rulesInjector,
|
||||
│ │ tasksTodowriteDisabler, writeExistingFileGuard, bashFileReadGuard,
|
||||
│ │ readImageResizer, todoDescriptionOverride, webfetchRedirectGuard,
|
||||
│ │ hashlineReadEnhancer, jsonErrorRecovery
|
||||
│ └─ createTransformHooks() # 5: claudeCodeHooks, keywordDetector, contextInjectorMessagesTransform,
|
||||
│ thinkingBlockValidator, toolPairValidator
|
||||
├─→ createContinuationHooks() # 7: stopContinuationGuard, compactionContextInjector,
|
||||
│ compactionTodoPreserver, todoContinuationEnforcer (boulder),
|
||||
│ unstableAgentBabysitter, backgroundNotificationHook, atlasHook
|
||||
└─→ createSkillHooks() # 2: categorySkillReminder, autoSlashCommand
|
||||
```
|
||||
|
||||
Each tier produces an array of `(input, output) => void` handlers; the matching OpenCode handler iterates and calls each in registration order.
|
||||
|
||||
## SUBSYSTEM INVENTORY
|
||||
|
||||
| Subdir | Files (.ts) | LOC | Purpose | Has AGENTS.md |
|
||||
|--------|-------------|-----|---------|---------------|
|
||||
| `agents/` | 96 | 19,042 | 11 agent factories + dynamic prompt builder | yes |
|
||||
| `hooks/` | 570 | 73,515 | ~50 lifecycle hooks across 57 dirs | yes |
|
||||
| `tools/` | 306 | 43,348 | 16 tool dirs producing 20–39 tools | yes |
|
||||
| `features/` | 389 | 68,410 | 20 feature modules (team-mode, background-agent, etc.) | yes |
|
||||
| `shared/` | 258 | 30,416 | Cross-cutting utilities, barrel-exported | yes |
|
||||
| `cli/` | 150 | 16,975 | Commander.js CLI: install, run, doctor, mcp-oauth | yes |
|
||||
| `plugin/` | 55 | 11,756 | 10 OpenCode hook handlers + hook composition | yes |
|
||||
| `config/` | 41 | 2,282 | 32 Zod v4 schema files | yes |
|
||||
| `plugin-handlers/` | 27 | 5,791 | 6-phase config loading pipeline | yes |
|
||||
| `openclaw/` | 26 | 3,291 | Bidirectional Discord/Telegram/HTTP integration | yes |
|
||||
| `__tests__/` | 22 | 274 | Plugin-level integration tests + perf fixtures | — |
|
||||
| `mcp/` | 7 | 205 | 3 built-in remote MCPs | yes |
|
||||
| `testing/` | 2 | 225 | Test utilities | — |
|
||||
|
||||
## NOTES
|
||||
|
||||
- `plugin-interface.ts` is the **only** layer that talks to OpenCode's `Plugin` API. Every other file goes through it.
|
||||
- Reach for `shared/` before adding helpers anywhere else — duplicate utilities WILL be flagged in review.
|
||||
- Path aliases are forbidden. Use relative imports within a module, barrel imports across modules.
|
||||
|
||||
+66
-44
@@ -5,30 +5,34 @@ description: Developer reference for all 11 Oh My OpenAgent agent definitions, f
|
||||
|
||||
# src/agents/ — 11 Agent Definitions
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
Agent factories following `createXXXAgent(model) → AgentConfig` pattern. Each has static `mode` property. Built via `buildAgent()` compositing factory + categories + skills.
|
||||
Agent factories follow `createXXXAgent(model) → AgentConfig` pattern. Each has static `mode` property. Built via `buildAgent()` compositing factory + categories + skills. Built-in agent registry: [`builtin-agents.ts`](file:///Users/yeongyu/local-workspaces/omo/src/agents/builtin-agents.ts) `agentSources`. Type definition: [`types.ts`](file:///Users/yeongyu/local-workspaces/omo/src/agents/types.ts) `BuiltinAgentName` (10 names + sisyphus-junior derived = 11 distinct agents).
|
||||
|
||||
## AGENT INVENTORY
|
||||
|
||||
| Agent | Model | Temp | Mode | Fallback Chain | Purpose |
|
||||
|-------|-------|------|------|----------------|---------|
|
||||
| **Sisyphus** | claude-opus-4-7 max | 0.1 | all | k2p5 -> kimi-k2.6 -> gpt-5.5 medium -> glm-5 -> big-pickle | Main orchestrator, plans + delegates |
|
||||
| **Hephaestus** | gpt-5.5 medium | 0.1 | all | — | Autonomous deep worker |
|
||||
| **Oracle** | gpt-5.5 high | 0.1 | subagent | gemini-3.1-pro high -> claude-opus-4-7 max | Read-only consultation |
|
||||
| **Librarian** | gpt-5.4-mini-fast | 0.1 | subagent | qwen3.5-plus -> minimax-m2.7-highspeed -> minimax-m2.7 -> claude-haiku-4-5 -> gpt-5.4-nano | External docs/code search |
|
||||
| **Explore** | gpt-5.4-mini-fast | 0.1 | subagent | qwen3.5-plus -> minimax-m2.7-highspeed -> minimax-m2.7 -> claude-haiku-4-5 -> gpt-5.4-nano | Contextual grep |
|
||||
| **Multimodal-Looker** | gpt-5.3-codex medium | 0.1 | subagent | k2p5 -> gemini-3-flash -> glm-4.6v -> gpt-5-nano | PDF/image analysis |
|
||||
| **Metis** | claude-opus-4-7 max | **0.3** | subagent | gpt-5.5 high -> gemini-3.1-pro high | Pre-planning consultant |
|
||||
| **Momus** | gpt-5.5 xhigh | 0.1 | subagent | claude-opus-4-7 max -> gemini-3.1-pro high | Plan reviewer |
|
||||
| **Atlas** | claude-sonnet-4-6 | 0.1 | primary | gpt-5.5 medium | Todo-list orchestrator |
|
||||
| **Prometheus** | claude-opus-4-7 max | 0.1 | — | internal planner | Strategic planner (internal) |
|
||||
| Agent | Model | Temp | Mode | Fallback Chain (top of) | Purpose |
|
||||
|-------|-------|------|------|--------------------------|---------|
|
||||
| **Sisyphus** | claude-opus-4-7 max | 0.1 | all | k2p5 → kimi-k2.6 → gpt-5.5 medium → glm-5 → big-pickle | Main orchestrator, plans + delegates |
|
||||
| **Hephaestus** | gpt-5.5 medium | 0.1 | all | (GPT-only) | Autonomous deep worker — "Legitimate Craftsman" |
|
||||
| **Oracle** | gpt-5.5 high | 0.1 | subagent | gemini-3.1-pro high → claude-opus-4-7 max → glm-5.1 | Read-only consultation |
|
||||
| **Librarian** | gpt-5.4-mini-fast | 0.1 | subagent | qwen3.5-plus → minimax-m2.7-highspeed → claude-haiku-4-5 → gpt-5.4-nano | External docs/code search |
|
||||
| **Explore** | gpt-5.4-mini-fast | 0.1 | subagent | qwen3.5-plus → minimax-m2.7-highspeed → claude-haiku-4-5 → gpt-5.4-nano | Contextual grep |
|
||||
| **Multimodal-Looker** | gpt-5.5 medium | 0.1 | subagent | kimi-k2.6 → glm-4.6v → gpt-5-nano | PDF/image analysis |
|
||||
| **Metis** | claude-opus-4-7 max | **0.3** | subagent | gpt-5.5 high → gemini-3.1-pro high → glm-5.1 → k2p5 | Pre-planning consultant |
|
||||
| **Momus** | gpt-5.5 xhigh | 0.1 | subagent | claude-opus-4-7 max → gemini-3.1-pro high → glm-5.1 | Plan reviewer |
|
||||
| **Atlas** | claude-sonnet-4-6 | 0.1 | primary | kimi-k2.6 → gpt-5.5 medium → minimax-m2.7 | Todo-list orchestrator |
|
||||
| **Prometheus** | claude-opus-4-7 max | 0.1 | primary | gpt-5.5 high → glm-5.1 → gemini-3.1-pro | Strategic planner (interview) |
|
||||
| **Sisyphus-Junior** | claude-sonnet-4-6 | 0.1 | all | user-configurable | Category-spawned executor |
|
||||
|
||||
Authoritative chains live in [`src/shared/model-requirements.ts`](file:///Users/yeongyu/local-workspaces/omo/src/shared/model-requirements.ts).
|
||||
|
||||
## TOOL RESTRICTIONS
|
||||
|
||||
Defined in [`src/shared/agent-tool-restrictions.ts`](file:///Users/yeongyu/local-workspaces/omo/src/shared/agent-tool-restrictions.ts).
|
||||
|
||||
| Agent | Denied Tools |
|
||||
|-------|-------------|
|
||||
| Oracle | write, edit, task, call_omo_agent |
|
||||
@@ -37,37 +41,41 @@ Agent factories following `createXXXAgent(model) → AgentConfig` pattern. Each
|
||||
| Multimodal-Looker | ALL except read |
|
||||
| Atlas | task, call_omo_agent |
|
||||
| Momus | write, edit, task |
|
||||
| Prometheus | enforces `.md`-only writes via `prometheus-md-only` hook (path-based, not tool-based) |
|
||||
|
||||
## TEAM-MODE ELIGIBILITY
|
||||
|
||||
Only **sisyphus, atlas, sisyphus-junior, hephaestus** can be team members. Read-only agents (oracle, librarian, explore, multimodal-looker, metis, momus, prometheus) are rejected at TeamSpec parse. See [`team-mode/AGENTS.md`](file:///Users/yeongyu/local-workspaces/omo/src/features/team-mode/AGENTS.md).
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
agents/
|
||||
├── sisyphus.ts # 559 LOC, main orchestrator
|
||||
├── hephaestus.ts # 507 LOC, autonomous worker
|
||||
├── oracle.ts # Read-only consultant
|
||||
├── librarian.ts # External search
|
||||
├── explore.ts # Codebase grep
|
||||
├── multimodal-looker.ts # Vision/PDF
|
||||
├── metis.ts # Pre-planning
|
||||
├── momus.ts # Plan review
|
||||
├── atlas/agent.ts # Todo orchestrator
|
||||
├── types.ts # AgentFactory, AgentMode
|
||||
├── agent-builder.ts # buildAgent() composition
|
||||
├── utils.ts # Agent utilities
|
||||
├── builtin-agents.ts # createBuiltinAgents() registry
|
||||
├── dynamic-agent-prompt-builder.ts # Dynamic prompt builder system
|
||||
├── dynamic-agent-core-sections.ts # Core prompt sections
|
||||
├── dynamic-agent-policy-sections.ts # Policy prompt sections
|
||||
├── dynamic-agent-tool-categorization.ts # Tool categorization
|
||||
├── dynamic-agent-category-skills-guide.ts # Category skills guide
|
||||
├── custom-agent-summaries.ts # Custom agent summaries
|
||||
├── env-context.ts # Environment context
|
||||
└── builtin-agents/ # maybeCreateXXXConfig conditional factories
|
||||
├── sisyphus-agent.ts
|
||||
├── hephaestus-agent.ts
|
||||
├── atlas-agent.ts
|
||||
├── general-agents.ts # collectPendingBuiltinAgents
|
||||
└── available-skills.ts
|
||||
├── sisyphus.ts # Main orchestrator router
|
||||
├── sisyphus/ # Model-specific variant prompts
|
||||
│ ├── default.ts, gemini.ts, gpt-5-4.ts, gpt-5-5.ts
|
||||
├── hephaestus.ts # Routes to model variant
|
||||
├── hephaestus/ # gpt.ts, gpt-5-3-codex.ts, gpt-5-4.ts, gpt-5-5.ts
|
||||
├── oracle.ts # Read-only consultant
|
||||
├── librarian.ts # External search
|
||||
├── explore.ts # Codebase grep
|
||||
├── multimodal-looker.ts # Vision/PDF
|
||||
├── metis.ts # Pre-planning
|
||||
├── momus.ts # Plan review
|
||||
├── atlas/agent.ts # Todo orchestrator
|
||||
├── prometheus/ # Strategic planner — system-prompt.ts, identity-constraints.ts, interview-mode.ts, plan-template.ts, gemini.ts, gpt.ts
|
||||
├── types.ts # BuiltinAgentName, AgentMode, AgentConfig
|
||||
├── builtin-agents.ts # agentSources registry (10 → 11 with sisyphus-junior)
|
||||
├── builtin-agents/ # maybeCreateXXXConfig conditional factories + general-agents.ts + available-skills.ts
|
||||
├── agent-builder.ts # buildAgent() composition
|
||||
├── utils.ts # agent utilities
|
||||
├── env-context.ts # environment context for prompts
|
||||
├── custom-agent-summaries.ts # custom-agent prompt summaries
|
||||
├── dynamic-agent-prompt-builder.ts # dynamic prompt builder
|
||||
├── dynamic-agent-core-sections.ts # core prompt sections
|
||||
├── dynamic-agent-policy-sections.ts # policy sections
|
||||
├── dynamic-agent-tool-categorization.ts # tool categorization for prompt
|
||||
└── dynamic-agent-category-skills-guide.ts # category-skill guidance
|
||||
```
|
||||
|
||||
## FACTORY PATTERN
|
||||
@@ -82,10 +90,24 @@ const createXXXAgent: AgentFactory = (model: string) => ({
|
||||
createXXXAgent.mode = "subagent" // or "primary" or "all"
|
||||
```
|
||||
|
||||
Model resolution: 4-step: override → category-default → provider-fallback → system-default. Defined in `shared/model-requirements.ts`.
|
||||
Model resolution: 4-step pipeline → override → category-default → provider-fallback → system-default. Defined in [`shared/model-resolution-pipeline.ts`](file:///Users/yeongyu/local-workspaces/omo/src/shared/model-resolution-pipeline.ts).
|
||||
|
||||
## MODES
|
||||
|
||||
- **primary**: Respects UI-selected model, uses fallback chain
|
||||
- **subagent**: Uses own fallback chain, ignores UI selection
|
||||
- **all**: Available in both contexts (Sisyphus-Junior)
|
||||
- **`primary`** — respects UI-selected model, uses fallback chain (Atlas, Prometheus)
|
||||
- **`subagent`** — uses own fallback chain, ignores UI selection (Oracle, Librarian, Explore, etc.)
|
||||
- **`all`** — available in both contexts (Sisyphus, Hephaestus, Sisyphus-Junior)
|
||||
|
||||
## CANONICAL ORDER
|
||||
|
||||
`Sisyphus → Hephaestus → Prometheus → Atlas` (primary core agents) then alphabetical for the rest. Enforced by [`installAgentSortShim()`](file:///Users/yeongyu/local-workspaces/omo/src/shared/agent-sort-shim.ts) — patches `Array.prototype.{toSorted,sort}` narrowly when ≥2 canonical core agents are in the array. See [`src/plugin-handlers/AGENTS.md`](file:///Users/yeongyu/local-workspaces/omo/src/plugin-handlers/AGENTS.md) for the full history.
|
||||
|
||||
## DYNAMIC PROMPT BUILDER
|
||||
|
||||
`dynamic-agent-prompt-builder.ts` composes per-agent system prompts at runtime by stitching:
|
||||
- Core sections (identity, mode, restrictions)
|
||||
- Policy sections (citation, verification, anti-patterns)
|
||||
- Tool categorization (per-domain tool guidance)
|
||||
- Category-skills guide (which skills load with which categories)
|
||||
|
||||
This is what the Sisyphus prompt's "AGENTS / CATEGORY + SKILLS" tables come from.
|
||||
|
||||
@@ -5,7 +5,7 @@ description: Developer reference for the Hephaestus autonomous deep worker agent
|
||||
|
||||
# src/agents/hephaestus/ -- Autonomous Deep Worker
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ description: Developer reference for the Prometheus strategic planner agent —
|
||||
|
||||
# src/agents/prometheus/ -- Strategic Planner
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ description: Developer reference for Sisyphus orchestrator model-specific prompt
|
||||
|
||||
# src/agents/sisyphus/ -- Orchestrator Variants
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# src/cli/ — CLI: install, run, doctor, mcp-oauth
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/cli/config-manager/ — CLI Installation Utilities
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/cli/doctor/ — Health Diagnostics (25 Check Files)
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/cli/run/ — Non-Interactive Session Launcher
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
+44
-23
@@ -1,57 +1,78 @@
|
||||
# src/config/ — Zod v4 Schema System
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
32 schema files composing `OhMyOpenCodeConfigSchema`. Zod v4 validation with `safeParse()`. All fields optional — omitted fields use plugin defaults.
|
||||
30 non-test schema files composing `OhMyOpenCodeConfigSchema`. Zod v4 validation with `safeParse()`. All fields optional — omitted fields use defaults from the schema. Auto-emitted to `assets/oh-my-opencode.schema.json` via `bun run build:schema`.
|
||||
|
||||
## SCHEMA TREE
|
||||
|
||||
```
|
||||
config/schema/
|
||||
├── oh-my-opencode-config.ts # ROOT: OhMyOpenCodeConfigSchema (composes all below)
|
||||
├── agent-names.ts # BuiltinAgentNameSchema (11), OverridableAgentNameSchema (14)
|
||||
├── oh-my-opencode-config.ts # ROOT: composes all sub-schemas
|
||||
├── agent-names.ts # BuiltinAgentNameSchema (10) + sisyphus-junior
|
||||
├── agent-overrides.ts # AgentOverrideConfigSchema (21 fields per agent)
|
||||
├── agent-definitions.ts # custom agent definition schema
|
||||
├── categories.ts # 8 built-in + custom categories
|
||||
├── hooks.ts # HookNameSchema (48 hooks)
|
||||
├── hooks.ts # HookNameSchema (50+ hooks)
|
||||
├── skills.ts # SkillsConfigSchema (sources, paths, recursive)
|
||||
├── commands.ts # BuiltinCommandNameSchema
|
||||
├── experimental.ts # Feature flags (plugin_load_timeout_ms min 1000)
|
||||
├── experimental.ts # Feature flags incl plugin_load_timeout_ms (min 1000), task_system, max_tools
|
||||
├── sisyphus.ts # SisyphusConfigSchema (task system)
|
||||
├── sisyphus-agent.ts # SisyphusAgentConfigSchema
|
||||
├── ralph-loop.ts # RalphLoopConfigSchema
|
||||
├── tmux.ts # TmuxConfigSchema + TmuxLayoutSchema
|
||||
├── websearch.ts # provider: "exa" | "tavily"
|
||||
├── claude-code.ts # CC compatibility settings
|
||||
├── claude-code.ts # CC compatibility settings (plugins, plugins_override)
|
||||
├── comment-checker.ts # AI comment detection config
|
||||
├── notification.ts # OS notification settings
|
||||
├── git-master.ts # commit_footer: boolean | string
|
||||
├── browser-automation.ts # provider: playwright | agent-browser | playwright-cli
|
||||
├── background-task.ts # Concurrency limits per model/provider
|
||||
├── git-env-prefix.ts # Git environment prefix config
|
||||
├── browser-automation.ts # provider: playwright | playwright-cli | agent-browser
|
||||
├── background-task.ts # Concurrency limits per model/provider, syncPollTimeoutMs
|
||||
├── fallback-models.ts # FallbackModelsConfigSchema
|
||||
├── runtime-fallback.ts # RuntimeFallbackConfigSchema
|
||||
├── runtime-fallback.ts # RuntimeFallbackConfigSchema (reactive provider fallback)
|
||||
├── babysitting.ts # Unstable agent monitoring
|
||||
├── dynamic-context-pruning.ts # Context pruning settings
|
||||
├── start-work.ts # StartWorkConfigSchema (auto_commit)
|
||||
├── openclaw.ts # OpenClaw integration settings
|
||||
├── git-env-prefix.ts # Git environment prefix config
|
||||
├── model-capabilities.ts # Model capabilities config
|
||||
└── internal/permission.ts # AgentPermissionSchema
|
||||
|
||||
├── start-work.ts # StartWorkConfigSchema (auto_commit)
|
||||
├── openclaw.ts # OpenClaw integration settings
|
||||
├── model-capabilities.ts # Model capabilities config
|
||||
├── keyword-detector.ts # disabled_keywords (ultrawork|search|analyze|team)
|
||||
└── team-mode.ts # TeamModeConfigSchema (enabled, max_parallel_members, max_members, tmux_visualization)
|
||||
```
|
||||
|
||||
## ROOT SCHEMA FIELDS (32)
|
||||
## ROOT SCHEMA FIELDS
|
||||
|
||||
`$schema`, `new_task_system_enabled`, `default_run_agent`, `disabled_mcps`, `disabled_agents`, `disabled_skills`, `disabled_hooks`, `disabled_commands`, `disabled_tools`, `hashline_edit`, `agents`, `categories`, `claude_code`, `sisyphus_agent`, `comment_checker`, `experimental`, `auto_update`, `skills`, `ralph_loop`, `background_task`, `notification`, `babysitting`, `git_master`, `browser_automation_engine`, `websearch`, `tmux`, `sisyphus`, `start_work`, `_migrations`, `model_fallback`, `model_capabilities`, `openclaw`, `mcp_env_allowlist`
|
||||
`$schema`, `new_task_system_enabled`, `default_run_agent`, `disabled_mcps`, `disabled_agents`, `disabled_skills`, `disabled_hooks`, `disabled_commands`, `disabled_tools`, `hashline_edit`, `agents`, `categories`, `claude_code`, `sisyphus_agent`, `comment_checker`, `experimental`, `auto_update`, `skills`, `ralph_loop`, `background_task`, `notification`, `babysitting`, `git_master`, `browser_automation_engine`, `websearch`, `tmux`, `sisyphus`, `start_work`, `_migrations`, `model_fallback`, `model_capabilities`, `openclaw`, `mcp_env_allowlist`, `keyword_detector`, **`team_mode`**, `runtime_fallback`, `dynamic_context_pruning`.
|
||||
|
||||
## AGENT OVERRIDE FIELDS (21)
|
||||
## TEAM_MODE SCHEMA
|
||||
|
||||
`model`, `variant`, `category`, `skills`, `temperature`, `top_p`, `prompt`, `prompt_append`, `tools`, `disable`, `description`, `mode`, `color`, `permission`, `maxTokens`, `thinking`, `reasoningEffort`, `textVerbosity`, `providerOptions`
|
||||
```jsonc
|
||||
{
|
||||
"team_mode": {
|
||||
"enabled": false, // gate for 12 team_* tools and conditional hooks
|
||||
"max_parallel_members": 4, // concurrent active members
|
||||
"max_members": 8, // hard cap on team size
|
||||
"tmux_visualization": false // render tmux pane layout for the team
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## HOW TO ADD CONFIG
|
||||
When `enabled: true`:
|
||||
- 12 `team_*` tools register
|
||||
- 4 team-mode hooks activate (status injector, mailbox injector, session events, tool gating)
|
||||
- `team-mode` built-in skill loads
|
||||
- Doctor check `cli/doctor/checks/team-mode.ts` runs
|
||||
|
||||
## AGENT OVERRIDE FIELDS (per-agent)
|
||||
|
||||
`model`, `variant`, `category`, `skills`, `temperature`, `top_p`, `prompt`, `prompt_append`, `tools`, `disable`, `description`, `mode`, `color`, `permission`, `maxTokens`, `thinking`, `reasoningEffort`, `textVerbosity`, `providerOptions`, `fallback_models`, `ultrawork`.
|
||||
|
||||
## HOW TO ADD A CONFIG FIELD
|
||||
|
||||
1. Create `src/config/schema/{name}.ts` with Zod schema
|
||||
2. Add field to `oh-my-opencode-config.ts` root schema
|
||||
3. Reference via `z.infer<typeof YourSchema>` for TypeScript types
|
||||
4. Access in handlers via `pluginConfig.{name}`
|
||||
3. Reference via `z.infer<typeof YourSchema>` for the TypeScript type
|
||||
4. Access in handlers via `pluginConfig.{field_name}` (snake_case JSON, snake_case TS field)
|
||||
5. Run `bun run build:schema` to regenerate `assets/oh-my-opencode.schema.json`
|
||||
|
||||
+55
-44
@@ -1,73 +1,84 @@
|
||||
# src/features/ — 19 Feature Modules
|
||||
# src/features/ — 20 Feature Modules
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
Standalone feature modules wired into plugin/ layer. Each is self-contained with own types, implementation, and tests.
|
||||
Standalone feature modules wired into `plugin/` layer. Each is self-contained with own types, implementation, and co-located tests. Most expose a single factory or class via `index.ts` barrel.
|
||||
|
||||
## MODULE MAP
|
||||
|
||||
| Module | Files | Complexity | Purpose |
|
||||
|--------|-------|------------|---------|
|
||||
| **opencode-skill-loader** | 33 | HIGH | YAML frontmatter skill loading from 4 scopes |
|
||||
| **background-agent** | 47 | HIGH | Task lifecycle, concurrency (5/model), polling, spawner pattern, circuit breaker |
|
||||
| **tmux-subagent** | 34 | HIGH | Tmux pane management, grid planning, session orchestration |
|
||||
| **mcp-oauth** | 18 | HIGH | OAuth 2.0 + PKCE + DCR (RFC 7591) for MCP servers |
|
||||
| **builtin-skills** | 17 | LOW | 8 skills: git-master, playwright, playwright-cli, agent-browser, dev-browser, frontend-ui-ux, review-work, ai-slop-remover |
|
||||
| **skill-mcp-manager** | 18 | HIGH | Tier-3 MCP client lifecycle per session (stdio + HTTP + OAuth step-up) |
|
||||
| **claude-code-plugin-loader** | 15 | MEDIUM | Unified plugin discovery from .opencode/plugins/ |
|
||||
| **builtin-commands** | 11 | LOW | Command templates: refactor, init-deep, handoff, etc. |
|
||||
| **claude-tasks** | 7 | MEDIUM | Task schema + file storage + OpenCode todo sync |
|
||||
| **claude-code-mcp-loader** | 6 | MEDIUM | .mcp.json loading with ${VAR} env expansion |
|
||||
| **context-injector** | 6 | MEDIUM | AGENTS.md/README.md injection into context |
|
||||
| **run-continuation-state** | 5 | LOW | Persistent state for `run` command continuation across sessions |
|
||||
| **hook-message-injector** | 5 | MEDIUM | System message injection for hooks |
|
||||
| **boulder-state** | 5 | LOW | Persistent state for multi-step operations |
|
||||
| **background-agent** | 47 | HIGH | Task lifecycle, concurrency (5/key), 3s polling, spawner pattern, circuit breaker |
|
||||
| **opencode-skill-loader** | 33 | HIGH | YAML frontmatter skill discovery from 4 scopes (project > opencode > user > global) |
|
||||
| **tmux-subagent** | 34 | HIGH | Tmux pane management, grid planning, session orchestration via `runTmuxCommand` |
|
||||
| **team-mode** | 24 dirs / 100+ files | HIGH | Parallel multi-agent coordination — 12 `team_*` tools, mailbox, tasklist, worktrees, optional tmux layout |
|
||||
| **mcp-oauth** | 18 | HIGH | OAuth 2.0 + PKCE + DCR (RFC 7591) + step-up auth for MCP servers |
|
||||
| **skill-mcp-manager** | 18 | HIGH | Tier-3 MCP client lifecycle per session (stdio + HTTP + OAuth) |
|
||||
| **claude-code-plugin-loader** | 16 | MEDIUM | Unified Claude Code plugin discovery (commands, agents, skills, hooks, MCPs) |
|
||||
| **builtin-skills** | 17 | LOW–MED | 10 built-in skill files (git-master, playwright, frontend-ui-ux, review-work, ai-slop-remover, dev-browser, playwright-cli, **team-mode**, …) |
|
||||
| **builtin-commands** | 11 | LOW | Command templates: refactor, init-deep, handoff, ulw-loop, etc. |
|
||||
| **claude-tasks** | 7 | MEDIUM | Sisyphus task schema + atomic file storage + OpenCode todo API sync |
|
||||
| **claude-code-mcp-loader** | 11 | MEDIUM | Tier-2 MCP loader: `.mcp.json` parse + `${VAR}` env expansion |
|
||||
| **context-injector** | 6 | MEDIUM | AGENTS.md/README.md injection into session context |
|
||||
| **run-continuation-state** | 5 | LOW | Persistent state for `oh-my-opencode run` continuation across invocations |
|
||||
| **hook-message-injector** | 5 | MEDIUM | System message injection helper used by hooks |
|
||||
| **boulder-state** | 5 | LOW | Persistent state for boulder/multi-step operations |
|
||||
| **task-toast-manager** | 4 | MEDIUM | Task progress notifications |
|
||||
| **tool-metadata-store** | 3 | LOW | Tool execution metadata cache |
|
||||
| **claude-code-session-state** | 3 | LOW | Subagent session state tracking |
|
||||
| **claude-code-command-loader** | 3 | LOW | Load commands from .opencode/commands/ |
|
||||
| **claude-code-agent-loader** | 3 | LOW | Load agents from .opencode/agents/ |
|
||||
| **claude-code-command-loader** | 3 | LOW | Load `/commands` from `.opencode/commands/` and Claude Code plugins |
|
||||
| **claude-code-agent-loader** | 3 | LOW | Load agents from `.opencode/agents/` and Claude Code plugins |
|
||||
|
||||
## KEY MODULES
|
||||
|
||||
### background-agent (47 files, ~10k LOC)
|
||||
### background-agent (~10k LOC)
|
||||
|
||||
Core orchestration engine. `BackgroundManager` manages task lifecycle:
|
||||
- States: pending → running → completed/error/cancelled/interrupt
|
||||
- Concurrency: per-model/provider limits via `ConcurrencyManager` (FIFO queue)
|
||||
- Polling: 3s interval, completion via idle events + stability detection (10s unchanged)
|
||||
- States: `pending → running → completed | error | cancelled | interrupt`
|
||||
- Concurrency: per-key (`${providerID}/${modelID}`) limits via `ConcurrencyManager` (FIFO queue)
|
||||
- Polling: 3s interval, completion detected via idle event AND stability detection (10s unchanged)
|
||||
- Circuit breaker: automatic failure detection and recovery
|
||||
- spawner/: 8 focused files composing via `SpawnerContext` interface
|
||||
- `spawner/`: 8 focused files composing via `SpawnerContext` interface
|
||||
|
||||
### opencode-skill-loader (33 files, ~3.2k LOC)
|
||||
### team-mode (~13k LOC)
|
||||
|
||||
Parallel multi-agent coordination, OFF by default. Subdirs:
|
||||
- `team-registry/` — load/validate `~/.omo/teams/{name}/config.json`
|
||||
- `team-state-store/` — durable runtime state with atomic locks
|
||||
- `team-runtime/` — `team_create`, status, shutdown lifecycle
|
||||
- `team-mailbox/` — async messaging (send/poll/ack)
|
||||
- `team-tasklist/` — shared tasks with atomic claiming
|
||||
- `team-worktree/` — git worktree per member
|
||||
- `team-layout-tmux/` — optional tmux pane visualization
|
||||
- `tools/` — 12 `team_*` tool implementations
|
||||
|
||||
Eligible members: sisyphus, atlas, sisyphus-junior, hephaestus only. See [`team-mode/AGENTS.md`](file:///Users/yeongyu/local-workspaces/omo/src/features/team-mode/AGENTS.md).
|
||||
|
||||
### opencode-skill-loader (~3.2k LOC)
|
||||
|
||||
4-scope skill discovery (project > opencode > user > global):
|
||||
- YAML frontmatter parsing from SKILL.md files
|
||||
- Skill merger with priority deduplication
|
||||
- Template resolution with variable substitution
|
||||
- Provider gating for model-specific skills
|
||||
|
||||
### tmux-subagent (34 files, ~3.6k LOC)
|
||||
### tmux-subagent (~3.6k LOC)
|
||||
|
||||
State-first tmux integration:
|
||||
- `TmuxSessionManager`: pane lifecycle, grid planning
|
||||
- Spawn action decider + target finder
|
||||
- Polling manager for session health
|
||||
- Event handlers for pane creation/destruction
|
||||
State-first tmux integration. Centralized tmux command execution through `src/shared/tmux/runner.ts` (`runTmuxCommand`). Direct `Bun.spawn(["tmux", ...])` is FORBIDDEN — would drift from retry/timeout discipline.
|
||||
|
||||
### builtin-skills (8 skill objects)
|
||||
### builtin-skills (10 skills)
|
||||
|
||||
| Skill | Size | MCP | Tools |
|
||||
|-------|------|-----|-------|
|
||||
| git-master | 1111 LOC | — | Bash |
|
||||
| playwright | 312 LOC | @playwright/mcp | — |
|
||||
| agent-browser | (in playwright.ts) | — | Bash(agent-browser:*) |
|
||||
| playwright-cli | 268 LOC | — | Bash(playwright-cli:*) |
|
||||
| dev-browser | 221 LOC | — | Bash |
|
||||
| frontend-ui-ux | 79 LOC | — | — |
|
||||
| review-work | ~LOC | --- | --- |
|
||||
| ai-slop-remover | ~LOC | --- | --- |
|
||||
| Skill | LOC | MCP | Notes |
|
||||
|-------|-----|-----|-------|
|
||||
| git-master | 1111 | — | Atomic commits, rebase, history search |
|
||||
| playwright | 312 | @playwright/mcp | Browser automation via MCP |
|
||||
| playwright-cli | 268 | — | Browser automation via CLI |
|
||||
| dev-browser | 221 | — | Persistent page state browser |
|
||||
| review-work | ~500 | — | 5-agent post-implementation review orchestrator |
|
||||
| ai-slop-remover | ~300 | — | Remove AI code patterns |
|
||||
| **team-mode** | — | — | Loaded only when `team_mode.enabled` (skill explains the 12 tools to agents) |
|
||||
| frontend-ui-ux | 79 | — | Design-first UI development |
|
||||
| (git-master-skill-metadata) | — | — | Companion to git-master |
|
||||
|
||||
Browser variant selected by `browserProvider` config: playwright (default) | playwright-cli | agent-browser.
|
||||
Browser variant selected by `browser_automation_engine` config: `playwright` (default) | `playwright-cli` | `agent-browser`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/features/background-agent/ — Core Orchestration Engine
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,50 +1,81 @@
|
||||
# src/features/builtin-skills/ -- 8 Built-in Skills
|
||||
# src/features/builtin-skills/ — 10 Built-in Skill Files
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
24 files. 8 built-in skills registered via `createBuiltinSkills()`. Each skill implements `BuiltinSkill` interface with name, description, content, and optional MCP config.
|
||||
Skills shipped inside the plugin (always available, no install). Registered via `createBuiltinSkills()`. Each skill implements the `BuiltinSkill` interface with name, description, content, and optional MCP config. Loaded by `opencode-skill-loader` with priority: project > opencode > user > **builtin**. User-installed skills with the same name override built-ins.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
builtin-skills/
|
||||
├── index.ts # Barrel exports
|
||||
├── skills.ts # createBuiltinSkills() factory
|
||||
├── skills.ts # createBuiltinSkills() factory — registers all 10 below
|
||||
├── types.ts # BuiltinSkill interface
|
||||
├── git-master/ # SKILL.md + resources
|
||||
├── frontend-ui-ux/ # SKILL.md
|
||||
├── agent-browser/ # SKILL.md
|
||||
├── dev-browser/ # SKILL.md
|
||||
└── skills/ # Skill implementations as .ts files
|
||||
├── git-master-sections/ # Git master prompt sections
|
||||
├── playwright.ts # Playwright + agent-browser + playwright-cli + dev-browser
|
||||
├── frontend-ui-ux.ts # Frontend UI/UX skill
|
||||
├── review-work.ts # 5-agent parallel review orchestrator
|
||||
└── ai-slop-remover.ts # AI code smell remover
|
||||
├── skills/
|
||||
│ ├── git-master.ts # 1111 LOC
|
||||
│ ├── git-master-skill-metadata.ts # Companion to git-master
|
||||
│ ├── playwright.ts # MCP variant + agent-browser
|
||||
│ ├── playwright-cli.ts # CLI variant
|
||||
│ ├── dev-browser.ts # Persistent page state
|
||||
│ ├── frontend-ui-ux.ts # Design-first UI guidance
|
||||
│ ├── review-work.ts # 5-agent post-implementation review
|
||||
│ ├── ai-slop-remover.ts # Remove AI-generated code patterns
|
||||
│ ├── team-mode.ts # 12 team_* tool documentation (gated)
|
||||
│ ├── git-master-sections/ # Git-master prompt sub-sections
|
||||
│ └── index.ts # skill barrel
|
||||
├── git-master/ # Resources for git-master skill
|
||||
├── frontend-ui-ux/ # Resources for frontend-ui-ux skill
|
||||
├── agent-browser/ # Resources for agent-browser variant
|
||||
└── dev-browser/ # Resources for dev-browser
|
||||
```
|
||||
|
||||
## SKILL CATALOG
|
||||
|
||||
| Skill | LOC | MCP | Purpose |
|
||||
|-------|-----|-----|---------|
|
||||
| **git-master** | 1111 | -- | Atomic commits, rebase, history search |
|
||||
| **playwright** | 312 | @playwright/mcp | Browser automation via MCP |
|
||||
| **playwright-cli** | 268 | -- | Browser automation via CLI |
|
||||
| **agent-browser** | (in playwright.ts) | -- | Browser via agent-browser tool |
|
||||
| **dev-browser** | 221 | -- | Persistent page state browser |
|
||||
| **frontend-ui-ux** | 79 | -- | Design-first UI development |
|
||||
| **review-work** | ~500 | -- | 5-agent post-implementation review |
|
||||
| **ai-slop-remover** | ~300 | -- | Remove AI code patterns |
|
||||
| Skill | Approx LOC | MCP | Notes |
|
||||
|-------|------------|-----|-------|
|
||||
| `git-master` | 1111 | — | Atomic commits, rebase, history search; included by default for delegate-task `git` category |
|
||||
| `playwright` | 312 | `@playwright/mcp` | Browser automation via MCP |
|
||||
| `playwright-cli` | 268 | — | Browser automation via shell CLI (no MCP) |
|
||||
| `agent-browser` | (in playwright.ts) | — | Browser via `agent-browser:*` Bash commands |
|
||||
| `dev-browser` | 221 | — | Persistent page state browser for dev work |
|
||||
| `frontend-ui-ux` | 79 | — | Design-first UI development guidance |
|
||||
| `review-work` | ~500 | — | Post-implementation review orchestrator (5 parallel agents) |
|
||||
| `ai-slop-remover` | ~300 | — | Remove AI-generated code smells |
|
||||
| `team-mode` | — | — | **Conditional** — only loaded when `team_mode.enabled`; documents the 12 `team_*` tools and lifecycle |
|
||||
|
||||
## BROWSER VARIANT SELECTION
|
||||
|
||||
Config `browser_automation_engine` selects which browser skill loads:
|
||||
- `"playwright"` (default) -> playwright with @playwright/mcp
|
||||
- `"playwright-cli"` -> CLI-based playwright
|
||||
- `"agent-browser"` -> agent-browser tool
|
||||
|
||||
## SKILL LOADING
|
||||
| Value | Skill Loaded |
|
||||
|-------|-------------|
|
||||
| `"playwright"` (default) | playwright (MCP-backed) |
|
||||
| `"playwright-cli"` | playwright-cli (CLI-backed) |
|
||||
| `"agent-browser"` | agent-browser (in playwright.ts) |
|
||||
|
||||
Skills loaded by `opencode-skill-loader` with priority: project > opencode > user > builtin. User-installed skills with same name override built-ins.
|
||||
Only one browser skill is active per session — non-selected variants are skipped.
|
||||
|
||||
## TEAM-MODE SKILL GATING
|
||||
|
||||
The `team-mode` skill is registered unconditionally but only **rendered** when `team_mode.enabled: true`:
|
||||
|
||||
```typescript
|
||||
// skills/team-mode.ts (paraphrase)
|
||||
const teamModeSkill: BuiltinSkill = {
|
||||
name: "team-mode",
|
||||
shouldLoad: (config) => config.team_mode?.enabled === true,
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
When disabled, the skill is filtered out before agent prompt assembly so agents do not see `team_*` tool docs they cannot use.
|
||||
|
||||
## ADDING A NEW BUILT-IN SKILL
|
||||
|
||||
1. Create `skills/{name}.ts` exporting a `BuiltinSkill` object
|
||||
2. Register in `skills.ts` `createBuiltinSkills()` factory
|
||||
3. Add resources (if any) under a sibling directory: `{name}/SKILL.md`, prompt sections, etc.
|
||||
4. If the skill is conditional, set `shouldLoad: (config) => …`
|
||||
5. Optionally declare an MCP server in the skill (loaded by `skill-mcp-manager` per session)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/features/claude-code-mcp-loader/ — Tier 2 MCP Loader (.mcp.json)
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/features/claude-code-plugin-loader/ — Unified Claude Code Plugin Loader
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/features/claude-tasks/ — Task Schema + Storage
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/features/mcp-oauth/ — OAuth 2.0 + PKCE + DCR for MCP Servers
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/features/opencode-skill-loader/ — 4-Scope Skill Discovery
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/features/skill-mcp-manager/ — Skill-Embedded MCP Client Lifecycle
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,92 +1,160 @@
|
||||
# team-mode — Parallel Multi-Agent Coordination
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
Parity with Claude Code Agent Teams. OFF by default. Enable via `team_mode.enabled` in config.
|
||||
Spawns coordinated agent teams with shared mailbox, task list, optional tmux layout, and graceful lifecycle. Modeled after Claude Code Agent Teams. **OFF by default.** Enable via `team_mode.enabled` in `oh-my-opencode.jsonc`; restart OpenCode after enabling.
|
||||
|
||||
Spawns coordinated agent teams with shared mailbox, task list, and lifecycle management. Lead delegates, members claim tasks, graceful shutdown with acks.
|
||||
User docs: [`docs/guide/team-mode.md`](file:///Users/yeongyu/local-workspaces/omo/docs/guide/team-mode.md).
|
||||
|
||||
## CONFIG
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"team_mode": {
|
||||
"enabled": true,
|
||||
"max_parallel_members": 4, // concurrent active members
|
||||
"max_members": 8, // hard cap on team size
|
||||
"tmux_visualization": false // optional tmux pane layout
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Schema: [`src/config/schema/team-mode.ts`](file:///Users/yeongyu/local-workspaces/omo/src/config/schema/team-mode.ts).
|
||||
|
||||
## 12 TEAM_* TOOLS
|
||||
|
||||
Registered via [`src/plugin/tool-registry.ts`](file:///Users/yeongyu/local-workspaces/omo/src/plugin/tool-registry.ts) `teamModeToolsRecord` only when enabled.
|
||||
|
||||
| Tool | Source File | Purpose |
|
||||
|------|-------------|---------|
|
||||
| `team_create` | `tools/lifecycle.ts` | Spawn team + member sessions from named or inline TeamSpec |
|
||||
| `team_delete` | `tools/lifecycle.ts` | Tear down state, mailbox, tasklist, worktrees, optional tmux |
|
||||
| `team_shutdown_request` | `tools/lifecycle.ts` | Member or lead requests its own shutdown |
|
||||
| `team_approve_shutdown` | `tools/lifecycle.ts` | Lead acks shutdown |
|
||||
| `team_reject_shutdown` | `tools/lifecycle.ts` | Lead rejects shutdown with reason |
|
||||
| `team_send_message` | `tools/messaging.ts` | Send to member name or `*` broadcast |
|
||||
| `team_task_create` | `tools/tasks.ts` | Create task on shared list |
|
||||
| `team_task_list` | `tools/tasks.ts` | List tasks (filter by status / owner) |
|
||||
| `team_task_update` | `tools/tasks.ts` | Claim / complete / delete (atomic file lock) |
|
||||
| `team_task_get` | `tools/tasks.ts` | Fetch single task |
|
||||
| `team_status` | `tools/query.ts` | Full team run status (members, tasks, mailbox) |
|
||||
| `team_list` | `tools/query.ts` | List declared + active teams |
|
||||
|
||||
## ELIGIBLE AGENTS
|
||||
|
||||
```
|
||||
ALLOWED: sisyphus, atlas, sisyphus-junior, hephaestus
|
||||
REJECTED at parse: oracle, librarian, explore, multimodal-looker, metis, momus, prometheus
|
||||
```
|
||||
|
||||
Read-only and orchestration-only agents are blocked at TeamSpec parse time. For those, the lead delegates via `task` (delegate-task) instead.
|
||||
|
||||
Eligibility registry: [`types.ts`](file:///Users/yeongyu/local-workspaces/omo/src/features/team-mode/types.ts) `AGENT_ELIGIBILITY_REGISTRY`.
|
||||
|
||||
## MEMBER KINDS
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"members": [
|
||||
{ "kind": "subagent_type", "name": "scout", "subagent_type": "sisyphus" },
|
||||
{ "kind": "category", "name": "writer", "category": "writing", "prompt": "Write release notes" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `kind: "subagent_type"` — direct agent. `prompt` optional.
|
||||
- `kind: "category"` — routed through `sisyphus-junior` with the chosen category model. `prompt` REQUIRED.
|
||||
|
||||
## MODULE LAYOUT
|
||||
|
||||
```
|
||||
team-mode/
|
||||
├── index.ts # barrel exports (types, worktree)
|
||||
├── types.ts # Zod schemas: TeamSpec, Member, Message, Task, RuntimeState
|
||||
├── member-parser.ts # member validation with eligibility registry
|
||||
├── deps.ts # dependency injection types
|
||||
├── team-session-registry.ts # in-memory sessionId -> team/member map for spawn-race-safe lookups
|
||||
├── team-registry/ # team spec loading from ~/.omo/teams/
|
||||
│ ├── index.ts
|
||||
│ ├── loader.ts # load from user + project scopes
|
||||
│ ├── paths.ts # path resolution
|
||||
│ └── validator.ts # TeamSpec validation
|
||||
├── team-state-store/ # durable runtime state
|
||||
│ ├── index.ts
|
||||
│ ├── store.ts # CRUD for state.json
|
||||
│ ├── resume.ts # resume orphaned runs
|
||||
│ └── locks.ts # atomic file locks
|
||||
├── team-runtime/ # team lifecycle
|
||||
│ ├── index.ts
|
||||
│ ├── create.ts # team_create implementation
|
||||
│ ├── status.ts # team_status implementation
|
||||
│ ├── shutdown.ts # shutdown request/approve/reject
|
||||
│ ├── resolve-member.ts # member agent resolution
|
||||
│ └── resolve-member-dependencies.ts
|
||||
├── team-mailbox/ # async messaging
|
||||
│ ├── index.ts
|
||||
│ ├── send.ts # team_send_message
|
||||
│ ├── poll.ts # inbox polling
|
||||
│ ├── ack.ts # message ack
|
||||
│ └── inbox.ts # inbox file ops
|
||||
├── team-tasklist/ # shared task list
|
||||
│ ├── index.ts
|
||||
│ ├── store.ts # task CRUD
|
||||
│ ├── list.ts # team_task_list
|
||||
│ ├── get.ts # team_task_get
|
||||
│ ├── update.ts # team_task_update (claim, complete)
|
||||
│ ├── claim.ts # task claiming with locks
|
||||
│ └── dependencies.ts # task dependency graph
|
||||
├── team-worktree/ # git worktree per member
|
||||
│ ├── index.ts
|
||||
│ ├── manager.ts # worktree lifecycle
|
||||
│ └── cleanup.ts # worktree removal
|
||||
├── team-layout-tmux/ # optional tmux visualization
|
||||
│ ├── index.ts
|
||||
│ ├── layout.ts # pane layout management
|
||||
│ ├── close-team-member-pane.ts # close member pane + rebalance window
|
||||
│ ├── rebalance-team-window.ts # redistribute layout after pane changes
|
||||
│ └── sweep-stale-team-sessions.ts # garbage-collect orphaned team tmux sessions
|
||||
└── tools/ # 12 team_* tools
|
||||
├── index.ts # tool registration
|
||||
├── lifecycle.ts # create, delete, shutdown
|
||||
├── messaging.ts # send_message
|
||||
├── tasks.ts # task_create, list, update, get
|
||||
└── query.ts # status, list
|
||||
├── index.ts # barrel
|
||||
├── types.ts # Zod schemas: TeamSpec, Member, Message, Task, RuntimeState; AGENT_ELIGIBILITY_REGISTRY
|
||||
├── deps.ts # checkTeamModeDependencies (git, tmux availability)
|
||||
├── member-parser.ts # member validation against eligibility registry
|
||||
├── member-guidance.ts # auto-injected guidance per member kind
|
||||
├── member-session-resolution.ts
|
||||
├── member-session-routing.ts
|
||||
├── resolve-caller-team-lead.ts # determine if a session is acting as lead
|
||||
├── team-session-registry.ts # spawn-race-safe sessionID → team/member lookups
|
||||
├── team-registry/ # team spec loading from ~/.omo/teams/{name}/config.json
|
||||
│ ├── loader.ts
|
||||
│ ├── paths.ts # ensureBaseDirs, resolveBaseDir
|
||||
│ └── validator.ts
|
||||
├── team-state-store/ # durable runtime state.json with atomic locks
|
||||
├── team-runtime/ # create/status/shutdown lifecycle
|
||||
├── team-mailbox/ # async messaging (send / poll / ack / inbox)
|
||||
├── team-tasklist/ # CRUD + claiming + dependencies
|
||||
├── team-worktree/ # one git worktree per member; cleanup on delete
|
||||
├── team-layout-tmux/ # optional pane layout — close-team-member-pane, sweep-stale-team-sessions
|
||||
└── tools/ # 12 team_* tool implementations + tests
|
||||
```
|
||||
|
||||
## STORAGE LAYOUT
|
||||
|
||||
See user guide: `docs/guide/team-mode.md`
|
||||
```
|
||||
~/.omo/teams/{name}/ # user scope
|
||||
<project>/.omo/teams/{name}/ # project scope (wins on collision)
|
||||
├── config.json # TeamSpec
|
||||
├── state.json # runtime: members, sessionIDs, lifecycle
|
||||
├── mailbox/ # one .jsonl per recipient
|
||||
├── tasklist.jsonl # shared task list
|
||||
└── worktrees/{member-name}/ # git worktree per member
|
||||
```
|
||||
|
||||
## LIFECYCLE
|
||||
|
||||
```
|
||||
1. team_create
|
||||
→ load TeamSpec → validate eligibility → spawn member sessions
|
||||
→ init mailbox + tasklist + worktrees → optional tmux layout
|
||||
2. Lead delegates via team_send_message + team_task_create
|
||||
3. Members claim tasks (team_task_update status="claimed") → execute → report (team_send_message)
|
||||
4. team_shutdown_request → team_approve_shutdown / team_reject_shutdown
|
||||
5. team_delete → cleanup state, mailbox, tasklist, worktrees, panes
|
||||
```
|
||||
|
||||
## KEY INVARIANTS
|
||||
|
||||
1. **Deferred ack**: Messages are fire-and-forget; recipient acks via separate call.
|
||||
2. **Locked tasks**: Task claiming uses atomic file locks; concurrent claims resolve safely.
|
||||
3. **Atomic writes**: All state changes write to temp file then rename.
|
||||
4. **Eligible agents only**: sisyphus, atlas, sisyphus-junior, hephaestus allowed. Read-only agents rejected at parse.
|
||||
5. **No nested teams**: Members cannot call `team_create`.
|
||||
6. **Spawn-race-safe session resolution**: Every team session spawn MUST call `registerTeamSession(sessionId, entry)` synchronously when the sessionID becomes known; every hook that resolves a sessionID to a team/member MUST call `lookupTeamSession` before falling back to `loadRuntimeState` to avoid the spawn-race window.
|
||||
1. **Spawn-race-safe resolution:** every team spawn calls `registerTeamSession(sessionId, entry)` synchronously when sessionID is known; every hook resolving sessionID calls `lookupTeamSession` BEFORE `loadRuntimeState` to avoid the spawn-race window.
|
||||
2. **Deferred ack:** messages are fire-and-forget; recipient acks via separate call.
|
||||
3. **Locked tasks:** task claiming uses atomic file locks; concurrent claims resolve safely.
|
||||
4. **Atomic writes:** state changes write to temp file then rename.
|
||||
5. **Eligible agents only:** rejection at parse, never at runtime.
|
||||
6. **No nested teams:** members CANNOT call `team_create`.
|
||||
|
||||
## INTEGRATION POINTS
|
||||
|
||||
| Where | What |
|
||||
|-------|------|
|
||||
| [`src/index.ts`](file:///Users/yeongyu/local-workspaces/omo/src/index.ts) (entry) | `checkTeamModeDependencies()` + `ensureBaseDirs()` if `team_mode.enabled` |
|
||||
| [`src/plugin/tool-registry.ts`](file:///Users/yeongyu/local-workspaces/omo/src/plugin/tool-registry.ts) | `teamModeToolsRecord` gate registers 12 tools |
|
||||
| `src/hooks/team-mode-status-injector/` | Injects `<team_mode_status>` block into messages |
|
||||
| `src/hooks/team-mailbox-injector/` | Pulls pending mailbox messages into agent context |
|
||||
| `src/hooks/team-session-events/` | React to member session lifecycle |
|
||||
| `src/hooks/team-tool-gating/` | Restrict `team_*` tools by member role |
|
||||
| [`src/cli/doctor/checks/team-mode.ts`](file:///Users/yeongyu/local-workspaces/omo/src/cli/doctor/checks/team-mode.ts) | Doctor check for team-mode prerequisites |
|
||||
| [`src/features/builtin-skills/skills/team-mode.ts`](file:///Users/yeongyu/local-workspaces/omo/src/features/builtin-skills/skills/team-mode.ts) | Built-in skill that documents the tools — only loaded when enabled |
|
||||
|
||||
## WHERE TO LOOK
|
||||
|
||||
| Task | Location |
|
||||
|------|----------|
|
||||
| Add new team tool | `tools/` + register in `index.ts` |
|
||||
| Modify member eligibility | `types.ts` AGENT_ELIGIBILITY_REGISTRY |
|
||||
| Add new team tool | `tools/` + register in [`src/plugin/tool-registry.ts`](file:///Users/yeongyu/local-workspaces/omo/src/plugin/tool-registry.ts) `teamModeToolsRecord` |
|
||||
| Modify member eligibility | `types.ts` `AGENT_ELIGIBILITY_REGISTRY` |
|
||||
| Change storage format | `types.ts` Zod schemas |
|
||||
| Add worktree features | `team-worktree/manager.ts` |
|
||||
| Add worktree behavior | `team-worktree/manager.ts` |
|
||||
| Modify tmux layout | `team-layout-tmux/layout.ts` |
|
||||
| Task lifecycle changes | `team-tasklist/` |
|
||||
| Mailbox protocol changes | `team-mailbox/` |
|
||||
| Recover orphaned runs | `team-state-store/resume.ts` |
|
||||
|
||||
## ANTI-PATTERNS
|
||||
|
||||
- Never bypass `team-session-registry` — direct `loadRuntimeState` lookups will hit the spawn-race window.
|
||||
- Never write team state files without the atomic lock from `team-state-store/locks.ts`.
|
||||
- Never substitute `task` (delegate-task) for `team_*` tools when the user explicitly asks for team-mode work — they are not equivalent.
|
||||
- Never allow members to call `team_create` (nested teams are forbidden by `team-tool-gating` hook).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/features/tmux-subagent/ — Tmux Pane Management
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
+125
-162
@@ -1,176 +1,139 @@
|
||||
# src/hooks/ — 52 Lifecycle Hooks
|
||||
# src/hooks/ — ~50 Lifecycle Hooks Across 57 Dirs
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
52 hooks across dedicated modules and standalone files. Three-tier composition: Core(43) + Continuation(7) + Skill(2). All hooks follow `createXXXHook(deps) → HookFunction` factory pattern.
|
||||
50 hooks (7 of the 57 dirs are `zauc-mocks-*` test scaffolds + 1 `shared/`). 5-tier composition wired in `src/plugin/hooks/`. All hooks follow `createXXXHook(deps) → HookFunction` factory pattern.
|
||||
|
||||
## HOOK TIERS
|
||||
## TIER COMPOSITION
|
||||
|
||||
| Tier | Composer | Count | When |
|
||||
|------|----------|-------|------|
|
||||
| **Session** | `create-session-hooks.ts` | 24 | OpenCode session lifecycle (created/idle/error/status) + chat.params + chat.message |
|
||||
| **Tool Guard** | `create-tool-guard-hooks.ts` | 14 | Pre/post tool execution |
|
||||
| **Transform** | `create-transform-hooks.ts` | 5 | `experimental.chat.messages.transform` |
|
||||
| **Continuation** | `create-continuation-hooks.ts` | 7 | Boulder/atlas/compaction/notification |
|
||||
| **Skill** | `create-skill-hooks.ts` | 2 | Skill awareness (categorySkillReminder, autoSlashCommand) |
|
||||
| **Team-mode** | conditional in registries | 4 | When `team_mode.enabled`: team-mailbox-injector, team-mode-status-injector, team-session-events, team-tool-gating |
|
||||
|
||||
### Tier 1: Session Hooks (24)
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| `contextWindowMonitor` | session.idle | Track context usage |
|
||||
| `preemptiveCompaction` | session.idle | Trigger compaction before limit |
|
||||
| `sessionRecovery` | session.error | Recover from structural errors (tool_result_missing, thinking_block_order) |
|
||||
| `sessionNotification` | session.idle | OS notifications on completion |
|
||||
| `thinkMode` | chat.params | Model variant switching for extended thinking |
|
||||
| `anthropicContextWindowLimitRecovery` | session.error | Multi-strategy context recovery (truncation, compaction, dedup) |
|
||||
| `autoUpdateChecker` | session.created | Check npm for plugin updates |
|
||||
| `agentUsageReminder` | chat.message | Remind about available agents |
|
||||
| `nonInteractiveEnv` | chat.message | Adjust behavior for `run` command |
|
||||
| `interactiveBashSession` | tool.execute | Tmux session lifecycle for interactive_bash tool |
|
||||
| `ralphLoop` | event | Self-referential dev loop (boulder continuation) |
|
||||
| `editErrorRecovery` | tool.execute.after | Retry failed file edits |
|
||||
| `delegateTaskRetry` | tool.execute.after | Retry failed task delegations |
|
||||
| `startWork` | chat.message | `/start-work` command handler |
|
||||
| `prometheusMdOnly` | tool.execute.before | Enforce .md-only writes for Prometheus |
|
||||
| `sisyphusJuniorNotepad` | chat.message | Notepad injection for subagents |
|
||||
| `questionLabelTruncator` | tool.execute.before | Truncate long Question tool labels |
|
||||
| `taskResumeInfo` | chat.message | Inject task context on resume |
|
||||
| `anthropicEffort` | chat.params | Adjust reasoning effort level |
|
||||
| `modelFallback` | chat.params | Provider-level proactive model fallback |
|
||||
| `noSisyphusGpt` | chat.message | Block Sisyphus from non-GPT providers (with warning toast) |
|
||||
| `noHephaestusNonGpt` | chat.message | Block Hephaestus from non-GPT models |
|
||||
| `runtimeFallback` | event | Reactive auto-switch on API provider errors |
|
||||
| `legacyPluginToast` | chat.message | Show toast when legacy plugin name detected |
|
||||
|
||||
### Tier 2: Tool Guard Hooks (14)
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| `commentChecker` | tool.execute.after | Block AI-slop comment patterns (binary: `@code-yeongyu/comment-checker`) |
|
||||
| `toolOutputTruncator` | tool.execute.after | Truncate oversized tool output |
|
||||
| `directoryAgentsInjector` | tool.execute.before | Inject dir-local AGENTS.md into context |
|
||||
| `directoryReadmeInjector` | tool.execute.before | Inject dir-local README.md into context |
|
||||
| `emptyTaskResponseDetector` | tool.execute.after | Detect empty task results |
|
||||
| `rulesInjector` | tool.execute.before | Conditional rules injection (AGENTS.md, .rules) |
|
||||
| `tasksTodowriteDisabler` | tool.execute.before | Disable TodoWrite when Sisyphus task system active |
|
||||
| `writeExistingFileGuard` | tool.execute.before | Require Read before Write/Edit on existing files |
|
||||
| `bashFileReadGuard` | tool.execute.before | Guard bash commands that read files (cat/head/tail) |
|
||||
| `readImageResizer` | tool.execute.after | Resize large images for context efficiency |
|
||||
| `todoDescriptionOverride` | tool.execute.before | Override todo item descriptions |
|
||||
| `webfetchRedirectGuard` | tool.execute.before | Guard webfetch redirect behavior |
|
||||
| `hashlineReadEnhancer` | tool.execute.after | Tag every Read output with `LINE#ID` content hashes |
|
||||
| `jsonErrorRecovery` | tool.execute.after | Detect JSON parse errors, inject correction reminder |
|
||||
|
||||
### Tier 3: Transform Hooks (5)
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| `claudeCodeHooks` | messages.transform | Claude Code settings.json compatibility |
|
||||
| `keywordDetector` | messages.transform | Detect ultrawork/search/analyze/team modes; inject mode-specific prompt |
|
||||
| `contextInjectorMessagesTransform` | messages.transform | Inject AGENTS.md/README.md into context |
|
||||
| `thinkingBlockValidator` | messages.transform | Validate thinking block structure |
|
||||
| `toolPairValidator` | messages.transform | Validate tool call/result pairing |
|
||||
|
||||
### Tier 4: Continuation Hooks (7)
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| `stopContinuationGuard` | chat.message | `/stop-continuation` command handler |
|
||||
| `compactionContextInjector` | session.compacted | Re-inject context after compaction |
|
||||
| `compactionTodoPreserver` | session.compacted | Preserve todos through compaction |
|
||||
| `todoContinuationEnforcer` | session.idle | **Boulder** — force continuation on incomplete todos |
|
||||
| `unstableAgentBabysitter` | session.idle | Monitor unstable agent behavior |
|
||||
| `backgroundNotificationHook` | event | Background task completion notifications |
|
||||
| `atlasHook` | event | Master orchestrator for boulder/background sessions |
|
||||
|
||||
### Tier 5: Skill Hooks (2)
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| `categorySkillReminder` | chat.message | Hint to load skills before invoking categories |
|
||||
| `autoSlashCommand` | chat.message | Auto-execute matching `/command` from user message |
|
||||
|
||||
### Team-mode Hooks (4, conditional)
|
||||
|
||||
Activated only when `team_mode.enabled: true`:
|
||||
|
||||
| Hook | Tier | Purpose |
|
||||
|------|------|---------|
|
||||
| `team-mode-status-injector` | Transform | Inject `<team_mode_status>` block into messages |
|
||||
| `team-mailbox-injector` | Transform | Pull pending team mailbox messages into agent context |
|
||||
| `team-session-events` | Continuation | React to member session lifecycle (created/idle/deleted) |
|
||||
| `team-tool-gating` | Tool Guard | Restrict `team_*` tools based on member role + permissions |
|
||||
|
||||
### Tier 1: Session Hooks (24) — `create-session-hooks.ts`
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
hooks/
|
||||
├── agent-usage-reminder/ # Reminds about available agents
|
||||
├── atlas/ # Main orchestration (757 lines)
|
||||
├── anthropic-context-window-limit-recovery/ # Auto-summarize
|
||||
├── anthropic-effort/ # Reasoning effort level adjustment
|
||||
├── auto-slash-command/ # Detects /command patterns
|
||||
├── auto-update-checker/ # Plugin update check
|
||||
├── background-notification/ # OS notification
|
||||
├── category-skill-reminder/ # Reminds of category skills
|
||||
├── claude-code-hooks/ # settings.json compat layer
|
||||
├── comment-checker/ # Prevents AI slop
|
||||
├── compaction-context-injector/ # Injects context on compaction
|
||||
├── compaction-todo-preserver/ # Preserves todos through compaction
|
||||
├── delegate-task-retry/ # Retries failed delegations
|
||||
├── directory-agents-injector/ # Auto-injects AGENTS.md
|
||||
├── directory-readme-injector/ # Auto-injects README.md
|
||||
├── edit-error-recovery/ # Recovers from failures
|
||||
├── hashline-edit-diff-enhancer/ # Enhanced diff output for hashline edits
|
||||
├── hashline-read-enhancer/ # Adds LINE#ID hashes to Read output
|
||||
├── interactive-bash-session/ # Tmux session management
|
||||
├── json-error-recovery/ # JSON parse error correction
|
||||
├── keyword-detector/ # ultrawork/search/analyze modes
|
||||
├── legacy-plugin-toast/ # Legacy plugin name migration toast
|
||||
├── model-fallback/ # Provider-level model fallback
|
||||
├── no-hephaestus-non-gpt/ # Block Hephaestus from non-GPT
|
||||
├── no-sisyphus-gpt/ # Block Sisyphus from GPT
|
||||
├── non-interactive-env/ # Non-TTY environment handling
|
||||
├── prometheus-md-only/ # Planner read-only mode
|
||||
├── question-label-truncator/ # Auto-truncates question labels
|
||||
├── ralph-loop/ # Self-referential dev loop
|
||||
├── read-image-resizer/ # Resize images for context efficiency
|
||||
├── rules-injector/ # Conditional rules
|
||||
├── runtime-fallback/ # Auto-switch models on API errors
|
||||
├── session-recovery/ # Auto-recovers from crashes
|
||||
├── sisyphus-junior-notepad/ # Sisyphus Junior notepad
|
||||
├── start-work/ # Sisyphus work session starter
|
||||
├── stop-continuation-guard/ # Guards stop continuation
|
||||
├── task-reminder/ # Task system usage reminders
|
||||
├── task-resume-info/ # Resume info for cancelled tasks
|
||||
├── tasks-todowrite-disabler/ # Disable TodoWrite when task system active
|
||||
├── think-mode/ # Dynamic thinking budget
|
||||
├── thinking-block-validator/ # Ensures valid <thinking>
|
||||
├── todo-continuation-enforcer/ # Force TODO completion
|
||||
├── todo-description-override/ # Override todo descriptions
|
||||
├── tool-pair-validator/ # Validate tool pair usage
|
||||
├── unstable-agent-babysitter/ # Monitor unstable agent behavior
|
||||
├── webfetch-redirect-guard/ # Guard webfetch redirect behavior
|
||||
├── write-existing-file-guard/ # Require Read before Write
|
||||
└── index.ts # Hook aggregation + registration
|
||||
├── shared/ # Cross-hook helpers (timing, prompt builders, etc.)
|
||||
├── (50 hook directories — see tier tables above)
|
||||
├── zauc-mocks-bg, zauc-mocks-cache, … # Test mocks (NOT hooks; named for sort-order isolation)
|
||||
└── (each hook dir)/
|
||||
├── index.ts # createXXXHook factory + barrel
|
||||
├── *.ts # implementation
|
||||
└── *.test.ts # bun:test
|
||||
```
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| contextWindowMonitor | session.idle | Track context window usage |
|
||||
| preemptiveCompaction | session.idle | Trigger compaction before limit |
|
||||
| sessionRecovery | session.error | Auto-retry on recoverable errors |
|
||||
| sessionNotification | session.idle | OS notifications on completion |
|
||||
| thinkMode | chat.params | Model variant switching (extended thinking) |
|
||||
| anthropicContextWindowLimitRecovery | session.error | Multi-strategy context recovery (truncation, compaction) |
|
||||
| autoUpdateChecker | session.created | Check npm for plugin updates |
|
||||
| agentUsageReminder | chat.message | Remind about available agents |
|
||||
| nonInteractiveEnv | chat.message | Adjust behavior for `run` command |
|
||||
| interactiveBashSession | tool.execute | Tmux session for interactive tools |
|
||||
| ralphLoop | event | Self-referential dev loop (boulder continuation) |
|
||||
| editErrorRecovery | tool.execute.after | Retry failed file edits |
|
||||
| delegateTaskRetry | tool.execute.after | Retry failed task delegations |
|
||||
| startWork | chat.message | `/start-work` command handler |
|
||||
| prometheusMdOnly | tool.execute.before | Enforce .md-only writes for Prometheus |
|
||||
| sisyphusJuniorNotepad | chat.message | Notepad injection for subagents |
|
||||
| questionLabelTruncator | tool.execute.before | Truncate long question labels |
|
||||
| taskResumeInfo | chat.message | Inject task context on resume |
|
||||
| anthropicEffort | chat.params | Adjust reasoning effort level |
|
||||
| modelFallback | chat.params | Provider-level model fallback on errors |
|
||||
| noSisyphusGpt | chat.message | Block Sisyphus from using GPT models (toast warning) |
|
||||
| noHephaestusNonGpt | chat.message | Block Hephaestus from using non-GPT models |
|
||||
| runtimeFallback | event | Auto-switch models on API provider errors |
|
||||
| legacyPluginToast | chat.message | Show toast when legacy plugin name detected |
|
||||
## ADDING A NEW HOOK
|
||||
|
||||
### Tier 2: Tool Guard Hooks (14) — `create-tool-guard-hooks.ts`
|
||||
1. `mkdir src/hooks/{name}` + `index.ts` exporting `createXXXHook(deps)`
|
||||
2. Pick the right tier:
|
||||
- Session lifecycle? → `create-session-hooks.ts`
|
||||
- Pre/post tool? → `create-tool-guard-hooks.ts`
|
||||
- Message transform? → `create-transform-hooks.ts`
|
||||
- Continuation/idle? → `create-continuation-hooks.ts`
|
||||
- Skill awareness? → `create-skill-hooks.ts`
|
||||
- Team-mode-only? → register inside the team-mode conditional block
|
||||
3. Add hook name to [`config/schema/hooks.ts`](file:///Users/yeongyu/local-workspaces/omo/src/config/schema/hooks.ts) `HookNameSchema`
|
||||
4. Cover with co-located `*.test.ts` (given/when/then style)
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| commentChecker | tool.execute.after | Block AI-generated comment patterns |
|
||||
| toolOutputTruncator | tool.execute.after | Truncate oversized tool output |
|
||||
| directoryAgentsInjector | tool.execute.before | Inject dir AGENTS.md into context |
|
||||
| directoryReadmeInjector | tool.execute.before | Inject dir README.md into context |
|
||||
| emptyTaskResponseDetector | tool.execute.after | Detect empty task responses |
|
||||
| rulesInjector | tool.execute.before | Conditional rules injection (AGENTS.md, config) |
|
||||
| tasksTodowriteDisabler | tool.execute.before | Disable TodoWrite when task system active |
|
||||
| writeExistingFileGuard | tool.execute.before | Require Read before Write on existing files |
|
||||
| bashFileReadGuard | tool.execute.before | Guard bash commands that read files |
|
||||
| readImageResizer | tool.execute.after | Resize large images for context efficiency |
|
||||
| todoDescriptionOverride | tool.execute.before | Override todo item descriptions |
|
||||
| webfetchRedirectGuard | tool.execute.before | Guard webfetch redirect behavior |
|
||||
| hashlineReadEnhancer | tool.execute.after | Enhance Read output with line hashes |
|
||||
| jsonErrorRecovery | tool.execute.after | Detect JSON parse errors, inject correction reminder |
|
||||
## NOTES
|
||||
|
||||
### Tier 3: Transform Hooks (5) — `create-transform-hooks.ts`
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| claudeCodeHooks | messages.transform | Claude Code settings.json compatibility |
|
||||
| keywordDetector | messages.transform | Detect ultrawork/search/analyze modes |
|
||||
| contextInjectorMessagesTransform | messages.transform | Inject AGENTS.md/README.md into context |
|
||||
| thinkingBlockValidator | messages.transform | Validate thinking block structure |
|
||||
| toolPairValidator | messages.transform | Validate tool call/result pairs |
|
||||
|
||||
### Tier 4: Continuation Hooks (7) — `create-continuation-hooks.ts`
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| stopContinuationGuard | chat.message | `/stop-continuation` command handler |
|
||||
| compactionContextInjector | session.compacted | Re-inject context after compaction |
|
||||
| compactionTodoPreserver | session.compacted | Preserve todos through compaction |
|
||||
| todoContinuationEnforcer | session.idle | **Boulder**: force continuation on incomplete todos |
|
||||
| unstableAgentBabysitter | session.idle | Monitor unstable agent behavior |
|
||||
| backgroundNotificationHook | event | Background task completion notifications |
|
||||
| atlasHook | event | Master orchestrator for boulder/background sessions |
|
||||
|
||||
### Tier 5: Skill Hooks (2) — `create-skill-hooks.ts`
|
||||
|
||||
| Hook | Event | Purpose |
|
||||
|------|-------|---------|
|
||||
| categorySkillReminder | chat.message | Remind about category+skill delegation |
|
||||
| autoSlashCommand | chat.message | Auto-detect `/command` in user input |
|
||||
|
||||
## KEY HOOKS (COMPLEX)
|
||||
|
||||
### anthropic-context-window-limit-recovery (31 files, ~2232 LOC)
|
||||
Multi-strategy recovery when hitting context limits. Strategies: truncation, compaction, summarization.
|
||||
|
||||
### atlas (17 files, ~1976 LOC)
|
||||
Master orchestrator for boulder sessions. Decision gates: session type → abort check → failure count → background tasks → agent match → plan completeness → cooldown (5s). Injects continuation prompts on session.idle.
|
||||
|
||||
### ralph-loop (14 files, ~1687 LOC)
|
||||
Self-referential dev loop via `/ralph-loop` command. State persisted in `.sisyphus/ralph-loop.local.md`. Detects `<promise>DONE</promise>` in AI output. Max 100 iterations default.
|
||||
|
||||
### todo-continuation-enforcer (13 files, ~2061 LOC)
|
||||
"Boulder" mechanism. Forces agent to continue when todos remain incomplete. 2s countdown toast → continuation injection. Exponential backoff: 30s base, ×2 per failure, max 5 consecutive failures then 5min pause.
|
||||
|
||||
### keyword-detector (~1665 LOC)
|
||||
Detects modes from user input: ultrawork, search, analyze, prove-yourself. Injects mode-specific system prompts.
|
||||
|
||||
### rules-injector (19 files, ~1604 LOC)
|
||||
Conditional rules injection from AGENTS.md, config, skill rules. Evaluates conditions to determine which rules apply.
|
||||
|
||||
## STANDALONE HOOKS (in src/hooks/ root)
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| context-window-monitor.ts | Track context window percentage |
|
||||
| preemptive-compaction.ts | Trigger compaction before hard limit |
|
||||
| tool-output-truncator.ts | Truncate tool output by token count |
|
||||
| session-notification.ts + 4 helpers | OS notification on session completion |
|
||||
| empty-task-response-detector.ts | Detect empty/failed task responses |
|
||||
| session-todo-status.ts | Todo completion status tracking |
|
||||
|
||||
## HOW TO ADD A HOOK
|
||||
|
||||
1. Create `src/hooks/{name}/index.ts` with `createXXXHook(deps)` factory
|
||||
2. Register in appropriate tier file (`src/plugin/hooks/create-{tier}-hooks.ts`)
|
||||
3. Add hook name to `src/config/schema/hooks.ts` HookNameSchema
|
||||
4. Hook receives `(event, ctx)` — return value depends on event type
|
||||
- **Tier order matters within a phase:** within Session tier the registration order in `create-session-hooks.ts` determines invocation order — earlier hooks see un-mutated input, later hooks see accumulated output.
|
||||
- **Mock files** (`zauc-mocks-*`, `zauc-sync-mocks`) are NOT hooks. They are placed inside `src/hooks/` purely so `bun:test` discovers them in the right order — auto-isolated by `script/run-ci-tests.ts` because they use `mock.module()`.
|
||||
- **`atlasHook` vs `todoContinuationEnforcer`:** atlas handles boulder/ralph/subagent sessions, todoContinuationEnforcer handles the main Sisyphus session. Both fire on `session.idle` but check session type first.
|
||||
- **`runtime-fallback` vs `model-fallback`:** runtime-fallback is reactive (after error); model-fallback is proactive (chat.params). They operate independently.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/anthropic-context-window-limit-recovery/ — Multi-Strategy Context Recovery
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/atlas/ — Master Boulder Orchestrator
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/claude-code-hooks/ — Claude Code Compatibility
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/comment-checker/ — AI Slop Comment Blocker
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/keyword-detector/ — Mode Keyword Injection
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/ralph-loop/ — Self-Referential Dev Loop
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/rules-injector/ — Conditional Rules Injection
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/runtime-fallback/ — Reactive Provider Error Recovery
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/session-recovery/ — Auto Session Error Recovery
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/hooks/todo-continuation-enforcer/ — Boulder Continuation Mechanism
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# src/mcp/ — 3 Built-in Remote MCPs
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/openclaw/ — Bidirectional External Integration
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/plugin-handlers/ — 6-Phase Config Loading Pipeline
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## CRITICAL: AGENT ORDERING
|
||||
|
||||
|
||||
+51
-20
@@ -1,36 +1,38 @@
|
||||
# src/plugin/ — 10 OpenCode Hook Handlers + Hook Composition
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
Core glue layer. 20 source files assembling the 10 OpenCode hook handlers and composing 50 hooks into the PluginInterface. Every handler file corresponds to one OpenCode hook type.
|
||||
Core glue layer. Files assemble the 10 OpenCode hook handlers and compose the 5-tier hook system into the `PluginInterface`. Each handler file maps to one OpenCode hook type.
|
||||
|
||||
## HANDLER FILES
|
||||
|
||||
| File | OpenCode Hook | Purpose |
|
||||
|------|---------------|---------|
|
||||
| `config.ts` | `config` | 6-phase config loading pipeline |
|
||||
| `tool-registry.ts` | `tool` | 26 tools assembled from factories |
|
||||
| `chat-message.ts` | `chat.message` | First-message variant, session setup, keyword detection |
|
||||
| `chat-params.ts` | `chat.params` | Anthropic effort level, think mode |
|
||||
| `chat-headers.ts` | `chat.headers` | Copilot x-initiator header injection |
|
||||
| `event.ts` | `event` | Session lifecycle (created, deleted, idle, error) |
|
||||
| `tool-execute-before.ts` | `tool.execute.before` | Pre-tool guards (file guard, label truncator, rules injector) |
|
||||
| `tool-execute-after.ts` | `tool.execute.after` | Post-tool hooks (output truncation, comment checker, metadata) |
|
||||
| `messages-transform.ts` | `experimental.chat.messages.transform` | Context injection, thinking block validation |
|
||||
| `session-compacting.ts` | `experimental.session.compacting` | Context + todo preservation during compaction |
|
||||
| `skill-context.ts` | — | Skill/browser/category context for tool creation |
|
||||
| `config.ts` | `config` | 6-phase config loading pipeline (delegates to `plugin-handlers/`) |
|
||||
| `tool-registry.ts` | `tool` | 20–39 tools assembled with config gates (team-mode +12, task system +4, hashline +1, interactive_bash +1, look_at +1) |
|
||||
| `chat-message.ts` | `chat.message` | First-message variant resolution, session setup, keyword detection trigger |
|
||||
| `chat-params.ts` | `chat.params` | Anthropic effort, think mode, runtime fallback model override |
|
||||
| `chat-headers.ts` | `chat.headers` | Copilot `x-initiator` header injection |
|
||||
| `event.ts` | `event` | Session lifecycle (created/deleted/idle/error/status), openclaw dispatch, runtime fallback |
|
||||
| `tool-execute-before.ts` | `tool.execute.before` | Pre-tool guards |
|
||||
| `tool-execute-after.ts` | `tool.execute.after` | Post-tool hooks (truncation, comment-checker, hashline read tagging, json-error-recovery) |
|
||||
| `messages-transform.ts` | `experimental.chat.messages.transform` | Context injection, thinking-block validation, tool-pair validation, keyword detection |
|
||||
| `session-compacting.ts` | `experimental.session.compacting` | Context + todo preservation across compaction |
|
||||
| `skill-context.ts` | (helper) | Skill/browser/category context shared with tool creation |
|
||||
|
||||
## HOOK COMPOSITION (hooks/ subdir)
|
||||
|
||||
| File | Tier | Count |
|
||||
|------|------|-------|
|
||||
| `create-session-hooks.ts` | Session | 23 |
|
||||
| `create-session-hooks.ts` | Session | 24 |
|
||||
| `create-tool-guard-hooks.ts` | Tool Guard | 14 |
|
||||
| `create-transform-hooks.ts` | Transform | 5 |
|
||||
| `create-skill-hooks.ts` | Skill | 2 |
|
||||
| `create-core-hooks.ts` | Aggregator | Session + Guard + Transform = 42 |
|
||||
| `create-core-hooks.ts` | Aggregator | Session + Guard + Transform = 43 |
|
||||
|
||||
`createContinuationHooks()` (7) lives in `src/create-hooks.ts` next to `createCoreHooks()` and `createSkillHooks()`.
|
||||
|
||||
## SUPPORT FILES
|
||||
|
||||
@@ -39,16 +41,45 @@ Core glue layer. 20 source files assembling the 10 OpenCode hook handlers and co
|
||||
| `available-categories.ts` | Build `AvailableCategory[]` for agent prompt injection |
|
||||
| `session-agent-resolver.ts` | Resolve which agent owns a session |
|
||||
| `session-status-normalizer.ts` | Normalize session status across OpenCode versions |
|
||||
| `recent-synthetic-idles.ts` | Dedup rapid idle events |
|
||||
| `recent-synthetic-idles.ts` | Dedup rapid synthetic idle events |
|
||||
| `unstable-agent-babysitter.ts` | Track unstable agent behavior across sessions |
|
||||
| `types.ts` | `PluginContext`, `PluginInterface`, `ToolsRecord`, `TmuxConfig` |
|
||||
| `ultrawork-model-override.ts` | Ultrawork mode model override logic |
|
||||
| `ultrawork-db-model-override.ts` | DB-level model override for ultrawork |
|
||||
| `config-handler.ts` | Runtime config loading and caching |
|
||||
| `normalize-tool-arg-schemas.ts` | Coerce tool arg schemas into a normalized shape |
|
||||
|
||||
## TOOL REGISTRATION GATES
|
||||
|
||||
```typescript
|
||||
// src/plugin/tool-registry.ts
|
||||
const taskToolsRecord = isTaskSystemEnabled(config) ? { task_create, task_get, task_list, task_update } : {}
|
||||
const hashlineToolsRecord = config.hashline_edit ? { edit: createHashlineEditTool(ctx) } : {}
|
||||
const teamModeToolsRecord = config.team_mode?.enabled ? { team_create, team_delete, team_shutdown_request, team_approve_shutdown, team_reject_shutdown, team_send_message, team_task_create, team_task_list, team_task_update, team_task_get, team_status, team_list } : {}
|
||||
const lookAt = isMultimodalLookerEnabled ? { look_at: createLookAt(ctx) } : {}
|
||||
const interactiveBashTool = interactiveBashEnabled ? { interactive_bash } : {}
|
||||
|
||||
const allTools = {
|
||||
...builtinTools, // 6 LSP
|
||||
...createGrepTools(ctx),
|
||||
...createGlobTools(ctx),
|
||||
...createAstGrepTools(ctx),
|
||||
...createSessionManagerTools(ctx),
|
||||
...backgroundTools, // 2 background_*
|
||||
call_omo_agent, task,
|
||||
...lookAt,
|
||||
skill_mcp, skill,
|
||||
...interactiveBashTool,
|
||||
...teamModeToolsRecord, // +12 conditional
|
||||
...taskToolsRecord, // +4 conditional
|
||||
...hashlineToolsRecord, // +1 conditional
|
||||
}
|
||||
```
|
||||
|
||||
## KEY PATTERNS
|
||||
|
||||
- Each handler exports a function receiving `(hookRecord, ctx, pluginConfig, managers)` → returns OpenCode hook function
|
||||
- Handlers iterate over hook records, calling each hook with `(input, output)` in sequence
|
||||
- `safeHook()` wrapper in composition files catches errors per-hook without breaking the chain
|
||||
- Tool registry uses `filterDisabledTools()` before returning
|
||||
- Each handler exports a function receiving `(hookRecord, ctx, pluginConfig, managers)` → returns the OpenCode hook function.
|
||||
- Handlers iterate over hook records, calling each hook with `(input, output)` in registration order.
|
||||
- `safeHook()` wrapper isolates hook errors so one broken hook does not crash the chain.
|
||||
- `filterDisabledTools(allTools, disabled_tools)` prunes tools listed in `disabled_tools` config.
|
||||
- `experimental.max_tools` cap trims tool count when set (selects the highest-priority tools).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/shared/ — 100+ Utility Files
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
+77
-88
@@ -1,108 +1,97 @@
|
||||
# src/tools/ - 26 Tools Across 16 Directories
|
||||
# src/tools/ — 20–39 Tools Across 16 Directories
|
||||
|
||||
**Generated:** 2026-04-18
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
26 tools registered via `createToolRegistry()`. Two patterns: factory functions (`createXXXTool`) for 19 tools, direct `ToolDefinition` for 7 (LSP + interactive_bash).
|
||||
Tools registered via [`createToolRegistry()`](file:///Users/yeongyu/local-workspaces/omo/src/plugin/tool-registry.ts) in `src/plugin/`. Two patterns: factory functions (`createXXXTool`) for most tools, direct `ToolDefinition` exports for the 6 LSP tools and `interactive_bash`. The total exposed count varies between 20 (minimum) and 39 (with all flags on) based on config gates listed below.
|
||||
|
||||
## TOOL CATALOG
|
||||
|
||||
### Task Management (4)
|
||||
### Always On (20)
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `task_create` | `createTaskCreateTool` | subject, description, blockedBy, blocks, metadata, parentID |
|
||||
| `task_list` | `createTaskList` | (none) |
|
||||
| `task_get` | `createTaskGetTool` | id |
|
||||
| `task_update` | `createTaskUpdateTool` | id, subject, description, status, addBlocks, addBlockedBy, owner, metadata |
|
||||
| Group | Tools |
|
||||
|-------|-------|
|
||||
| **LSP** (6) | `lsp_goto_definition`, `lsp_find_references`, `lsp_symbols`, `lsp_diagnostics`, `lsp_prepare_rename`, `lsp_rename` |
|
||||
| **Search** (4) | `grep`, `glob`, `ast_grep_search`, `ast_grep_replace` |
|
||||
| **Sessions** (4) | `session_list`, `session_read`, `session_search`, `session_info` |
|
||||
| **Background tasks** (2) | `background_output`, `background_cancel` |
|
||||
| **Delegation** (2) | `task` (delegate, full skill+category support), `call_omo_agent` (named agent only: explore, librarian) |
|
||||
| **Skills/MCP** (2) | `skill` (load skill or invoke command), `skill_mcp` (call skill-embedded MCP tool/resource/prompt) |
|
||||
|
||||
### Delegation (1)
|
||||
### Conditional (up to +19)
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `task` | `createDelegateTask` | description, prompt, category, subagent_type, run_in_background, session_id, load_skills, command |
|
||||
| Tool(s) | Gate | Source |
|
||||
|---------|------|--------|
|
||||
| `look_at` | not in `disabled_agents` for `multimodal-looker` | `look-at/` |
|
||||
| `interactive_bash` | `isInteractiveBashEnabled(config)` (tmux config) | `interactive-bash/` |
|
||||
| `task_create`, `task_get`, `task_list`, `task_update` | `experimental.task_system` | `task/` |
|
||||
| `edit` (hashline-edit) | `hashline_edit: true` | `hashline-edit/` |
|
||||
| 12 `team_*` tools | `team_mode.enabled: true` | `../features/team-mode/tools/` |
|
||||
|
||||
**8 Built-in Categories**: visual-engineering, ultrabrain, deep, artistry, quick, unspecified-low, unspecified-high, writing
|
||||
### 12 team_* Tools (when team_mode enabled)
|
||||
|
||||
### Agent Invocation (1)
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `team_create` | Spawn team + member sessions from a TeamSpec (named or inline) |
|
||||
| `team_delete` | Tear down — removes mailbox, tasklist, worktrees, optional tmux layout |
|
||||
| `team_shutdown_request` | Member or lead requests its own shutdown |
|
||||
| `team_approve_shutdown` | Lead acks a pending shutdown |
|
||||
| `team_reject_shutdown` | Lead rejects a shutdown with reason |
|
||||
| `team_send_message` | Async message to specific member or `*` broadcast |
|
||||
| `team_task_create` | Create task on shared list |
|
||||
| `team_task_list` | List tasks (filter by status, owner) |
|
||||
| `team_task_update` | Claim/complete/delete (atomic file lock) |
|
||||
| `team_task_get` | Fetch single task |
|
||||
| `team_status` | Full team run status (members, tasks, mailbox) |
|
||||
| `team_list` | List declared + active teams |
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `call_omo_agent` | `createCallOmoAgent` | description, prompt, subagent_type, run_in_background, session_id |
|
||||
## DELEGATION CATEGORIES (built-in 8)
|
||||
|
||||
### Background Tasks (2)
|
||||
`task` (delegate) selects model by category; categories defined in `delegate-task/constants.ts`:
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `background_output` | `createBackgroundOutput` | task_id, block, timeout, full_session, include_thinking, message_limit, since_message_id, thinking_max_chars |
|
||||
| `background_cancel` | `createBackgroundCancel` | taskId, all |
|
||||
| Category | Default Model | Domain |
|
||||
|----------|---------------|--------|
|
||||
| `visual-engineering` | gemini-3.1-pro high | Frontend, UI/UX |
|
||||
| `ultrabrain` | gpt-5.5 xhigh | Hard logic / heavy reasoning |
|
||||
| `deep` | gpt-5.5 medium | Autonomous multi-step problem-solving |
|
||||
| `artistry` | gemini-3.1-pro high | Creative / unconventional approaches |
|
||||
| `quick` | gpt-5.4-mini-fast | Trivial single-file changes |
|
||||
| `unspecified-low` | claude-sonnet-4-6 | Moderate effort fallback |
|
||||
| `unspecified-high` | claude-opus-4-7 max | High effort fallback |
|
||||
| `writing` | gemini-3-flash | Documentation, prose |
|
||||
|
||||
### LSP Refactoring (6) - Direct ToolDefinition
|
||||
User-defined categories declared in `categories: { ... }` config override and add to this set.
|
||||
|
||||
| Tool | Parameters |
|
||||
|------|------------|
|
||||
| `lsp_goto_definition` | filePath, line, character |
|
||||
| `lsp_find_references` | filePath, line, character, includeDeclaration |
|
||||
| `lsp_symbols` | filePath, scope (document/workspace), query, limit |
|
||||
| `lsp_diagnostics` | filePath, severity |
|
||||
| `lsp_prepare_rename` | filePath, line, character |
|
||||
| `lsp_rename` | filePath, line, character, newName |
|
||||
## TOOL DIR LAYOUT
|
||||
|
||||
### Code Search (4)
|
||||
```
|
||||
tools/
|
||||
├── ast-grep/ # ast_grep_search, ast_grep_replace
|
||||
├── background-task/ # background_output, background_cancel (LLM interface; engine in features/background-agent)
|
||||
├── call-omo-agent/ # call_omo_agent (explore + librarian only)
|
||||
├── delegate-task/ # task — full delegation with categories + skills
|
||||
├── glob/ # glob (60s timeout, 100 file limit)
|
||||
├── grep/ # grep (60s timeout, 10MB limit)
|
||||
├── hashline-edit/ # edit — hash-anchored line edits with LINE#ID validation
|
||||
├── interactive-bash/ # interactive_bash — tmux session control
|
||||
├── look-at/ # look_at — image/PDF analysis
|
||||
├── lsp/ # 6 LSP tools (direct ToolDefinition)
|
||||
├── session-manager/ # 4 session_* tools
|
||||
├── skill/ # skill — load skill or run command
|
||||
├── skill-mcp/ # skill_mcp — call skill-embedded MCP servers
|
||||
├── slashcommand/ # discoverCommandsSync — feeds skill tool with /-command list
|
||||
├── task/ # 4 task_* tools (Sisyphus task system)
|
||||
└── index.ts # barrel exports
|
||||
```
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `ast_grep_search` | `createAstGrepTools` | pattern, lang, paths, globs, context |
|
||||
| `ast_grep_replace` | `createAstGrepTools` | pattern, rewrite, lang, paths, globs, dryRun |
|
||||
| `grep` | `createGrepTools` | pattern, path, include (60s timeout, 10MB limit) |
|
||||
| `glob` | `createGlobTools` | pattern, path (60s timeout, 100 file limit) |
|
||||
## ADDING A NEW TOOL
|
||||
|
||||
### Session History (4)
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `session_list` | `createSessionManagerTools` | (none) |
|
||||
| `session_read` | `createSessionManagerTools` | session_id, include_todos, limit |
|
||||
| `session_search` | `createSessionManagerTools` | query, session_id, case_sensitive, limit |
|
||||
| `session_info` | `createSessionManagerTools` | session_id |
|
||||
|
||||
### Skill/Command (2)
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `skill` | `createSkillTool` | name, user_message |
|
||||
| `skill_mcp` | `createSkillMcpTool` | mcp_name, tool_name/resource_name/prompt_name, arguments, grep |
|
||||
|
||||
### System (2)
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `interactive_bash` | Direct | tmux_command |
|
||||
| `look_at` | `createLookAt` | file_path, image_data, goal |
|
||||
|
||||
### Editing (1) - Conditional
|
||||
|
||||
| Tool | Factory | Parameters |
|
||||
|------|---------|------------|
|
||||
| `hashline_edit` | `createHashlineEditTool` | file, edits[] |
|
||||
|
||||
## DELEGATION CATEGORIES
|
||||
|
||||
| Category | Model | Domain |
|
||||
|----------|-------|--------|
|
||||
| visual-engineering | gemini-3.1-pro high | Frontend, UI/UX |
|
||||
| ultrabrain | gpt-5.5 xhigh | Hard logic |
|
||||
| deep | gpt-5.5 medium | Autonomous problem-solving |
|
||||
| artistry | gemini-3.1-pro high | Creative approaches |
|
||||
| quick | gpt-5.4-mini | Trivial tasks |
|
||||
| unspecified-low | claude-sonnet-4-6 | Moderate effort |
|
||||
| unspecified-high | claude-opus-4-7 max | High effort |
|
||||
| writing | gemini-3-flash | Documentation |
|
||||
|
||||
## HOW TO ADD A TOOL
|
||||
|
||||
1. Create `src/tools/{name}/index.ts` exporting factory
|
||||
2. Create `src/tools/{name}/types.ts` for parameter schemas
|
||||
3. Create `src/tools/{name}/tools.ts` for implementation
|
||||
4. Register in `src/plugin/tool-registry.ts`
|
||||
1. Create `src/tools/{name}/index.ts` with factory `createXXXTool`
|
||||
2. Add `types.ts` for parameter Zod schemas
|
||||
3. Add `tools.ts` (or single index.ts) for implementation
|
||||
4. Export factory from `src/tools/index.ts`
|
||||
5. Register in `src/plugin/tool-registry.ts`:
|
||||
- Always-on: spread into `allTools` directly
|
||||
- Conditional: build a `Record<string, ToolDefinition>` and gate-spread
|
||||
6. If the tool needs disabling, ensure it appears in `filterDisabledTools` allow-list (its name will be matched against `disabled_tools`)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/tools/background-task/ — Background Task Tool Wrappers
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/tools/call-omo-agent/ — Direct Agent Invocation Tool
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/tools/delegate-task/ — Task Delegation Engine
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/tools/hashline-edit/ — Hash-Anchored File Edit Tool
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# src/tools/lsp/ — LSP Tool Implementations
|
||||
|
||||
**Generated:** 2026-04-11
|
||||
**Generated:** 2026-05-08
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
|
||||
Reference in New Issue
Block a user