Problem
The laptop had ponytail (a lazy-coding ruleset) and superpowers (a skill library) installed as opencode plugins. Forge and Curly — the two remote lab nodes — had bare opencode installs with no plugins or skills. Every machine should run the same tooling so the workflow is consistent across the lab.
Investigation
The laptop's setup turned out to be a chain of symlinks:
opencode.jsonreferences./plugins/superpowers.jsand./plugins/ponytail.mjsplugins/superpowers.jsis a symlink tosuperpowers/.opencode/plugins/superpowers.js(a git clone of the superpowers repo)plugins/ponytail.mjsis a symlink tonode_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs(the npm package)
The symlinks matter: each plugin resolves its skills directory relative to its real file location. The superpowers plugin computes ../../skills from superpowers/.opencode/plugins/, landing on superpowers/skills. The ponytail plugin resolves ../../hooks from the npm package location. Copying the plugin files as plain files would break these relative paths.
Fix
On each machine (Forge, then Curly):
1. Copy the superpowers repo to ~/.config/opencode/superpowers/ (excluding .git).
2. Install the ponytail npm package: npm install @dietrichgebert/[email protected].
3. Create the plugin symlinks in ~/.config/opencode/plugins/ pointing at the real plugin files.
4. Write opencode.jsonc with the two plugin entries.
Verification
opencode debug configshows both skills paths registered:node_modules/@dietrichgebert/ponytail/skillssuperpowers/skillsopencode debug skilllists all 20 skills (6 ponytail + 14 superpowers).opencode runloads the plugins with no errors.- Ponytail defaults to
fullmode (no state file needed).
Lesson
When replicating a plugin setup across machines, copy the whole directory structure including symlinks — don't flatten the files. The relative-path resolution inside each plugin depends on where the real file lives, not where the symlink points.