code-yeongyu / code-yeongyu/oh-my-openagent

Skill tool override causes dual-cache divergence with opencode native — migration path to plugin hooks

Open
#2,015 5 comments 0 reactions 1 assignee Claimed by @code-yeongyu View on GitHub
enhancement
Dominant language
TypeScript
Stars
69.2k
Forks
5.7k
Avg merge
3h 2m
Merged PRs (30d)
620

Description

## Motivation

We're working toward **skill hot-reload** for opencode — the ability to add/modify SKILL.md files at runtime without restarting. During implementation, we discovered that oh-my-opencode's skill tool silently overrides opencode's native `SkillTool`, creating a dual-cache architecture that makes hot-reload impossible to implement correctly.

Upstream bug report: [anomalyco/opencode#14534](https://github.com/anomalyco/opencode/issues/14534)

## Problem

oh-my-opencode's `createSkillTool()` registers `tool: { skill: ... }` which **silently overrides** opencode's native `SkillTool` via last-write-wins in `tools[item.id]`. This creates two independent skill caches that can never be invalidated together.

| Aspect | opencode native | oh-my-opencode |
|--------|----------------|----------------|
| Discovery | `Skill.state()` via `Instance.state()` | `createSkillContext()` -> `mergeSkills()` |
| Cache | `Instance.state` (per directory, memoized) | Closure variable `cachedSkills` in `createSkillTool()` |
| Invalidation | Only via `State.dispose()` (nukes everything) | **None** (set once, never cleared) |
| Tool id | `"skill"` | `"skill"` — **overwrites native** |
| Scanned dirs | Same 7+ directories | Same 7+ directories + builtin skills |

### Impact

1. **Hot-reload impossible** — adding a SKILL.md at runtime is invisible to both caches
2. **Duplicate work** — both systems scan the same directories independently
3. **Slash commands diverge** — `Command.state()` reads native cache, LLM reads plugin cache
4. **Maintenance burden** — oh-my-opencode must track every change to opencode's skill discovery logic

## Plan

We're contributing PRs upstream to make hot-reload work. This requires changes on both sides:

### Upstream (opencode) — in progress
1. Plugin `skill.list`/`skill.load` hooks ([PR #11060](https://github.com/anomalyco/opencode/pull/11060)) — plugins inject skills into the native registry instead of replacing the tool
2. Granular `State.invalidate()` — clear just skill cache without destroying the instance
3. Cascade invalidation (Skill → Command → Agent state)
4. File watching + `Skill.Event.Changed` bus event

### oh-my-opencode — blocked on upstream hooks landing

Once `skill.list`/`skill.load` hooks are available:

**Remove:**
- `createSkillContext()` / `discoverAllSkills()` / `mergeSkills()` pipeline
- `createSkillTool()` that overrides native SkillTool
- `cachedSkillsByProvider` closure cache
- Filesystem discovery logic in `src/features/opencode-skill-loader/`

**Replace with:**
- `skill.list` hook — inject builtin skills (playwright, git-master, frontend-ui-ux, dev-browser)
- `skill.load` hook — serve skill content for builtin skills
- Let opencode's native `SkillTool` handle all skill serving to the LLM

**Keep:**
- Skill MCP management (per [#1797](https://github.com/code-yeongyu/oh-my-opencode/issues/1797))
- `category-skill-reminder` hook (reads from native skill list instead of own cache)
- Plan agent skill sections (reads from native skill list)
- Skill merge/priority config in `oh-my-opencode.json`

### Benefits
1. **Hot-reload works** — single cache, single invalidation point
2. **Less code** — drop ~1000 lines of discovery/merge logic
3. **Consistent** — slash commands, skill tool, plan agent all see the same skills
4. **Future-proof** — new skill sources in opencode automatically available

## Related

- [anomalyco/opencode#14534](https://github.com/anomalyco/opencode/issues/14534) — Upstream bug report on the override mechanism
- [anomalyco/opencode#11060](https://github.com/anomalyco/opencode/pull/11060) — PR adding plugin skill hooks
- [anomalyco/opencode#8751](https://github.com/anomalyco/opencode/issues/8751) — Hot-reload request
- [anomalyco/opencode#13409](https://github.com/anomalyco/opencode/pull/13409) — Hot-reload endpoint PR
- [#1797](https://github.com/code-yeongyu/oh-my-opencode/issues/1797) — mcporter proposal (complementary, focuses on MCP)
- [#974](https://github.com/code-yeongyu/oh-my-opencode/pull/974) — PR integrating plugin skills into discovery

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.