Uh oh!
There was an error while loading. Please reload this page.
Install the skill where opencode actually looks - #624
Merged
Conversation
skillLocations offered "OpenCode (Global)" and "OpenCode (Project)" at `skill/`, singular. opencode reads `skills/`, plural. It has never read either path we wrote. That list is both the wizard's install targets and the refresh set, so the typo failed in both directions and silently in both. Picking OpenCode in `basecamp skill` wrote a file opencode would never load, and reported success. An opencode user who installed the skill the plural way by hand then never got it refreshed on upgrade, because the refresh loop only visits paths in this list and skips ones that don't exist. Verified against real binaries into a temp HOME, with a stale SKILL.md pre-placed at ~/.config/opencode/skills/basecamp/: the pre-fix build leaves it reading "STALE", this build rewrites it byte-identical to the embedded skill. Worth recording: the skill already worked in opencode regardless, because opencode also searches ~/.agents/skills/<name>/SKILL.md, which is the canonical target `installSkillFiles` has always written. So this fixes the wizard and the refresh loop, not first-run coverage. The new test pins the literal paths instead of deriving them. The existing refresh test built its opencode path from the same wrong spelling the code had, so it asserted the bug was working. Search paths: https://opencode.ai/docs/skills/
Uh oh!
There was an error while loading. Please reload this page.
jeremy added a commit
that referenced
this pull request
Aug 5, 2026
#624 claimed opencode never read `~/.config/opencode/skill/basecamp/SKILL.md`. That was wrong. opencode takes an optional plural throughout — its own shipped docs table (verified against the 1.18.4 binary, not the docs site) reads: | Global skills | `~/.config/opencode/skill(s)/<name>/SKILL.md` | | Project skills | `.opencode/skill(s)/<name>/SKILL.md` | the same `agent(s)` / `command(s)` form used for its other directories. So the singular paths worked, and #624 did not repair a broken install — it moved the install target from one working path to another. What it did break is upgrades: anyone who picked OpenCode in `basecamp skill` before #624 has a file opencode still loads, but which the refresh loop no longer visits, because that loop iterates the same list. Their skill keeps working and silently stops updating, which is worse than failing, since nothing reports it. The two roles that list plays are now separated. skillLocations stays the wizard's install targets. legacySkillLocations holds paths an agent still reads but that we no longer suggest, and refreshAllInstalledSkills walks both. Refresh updates in place and never creates the new path, so nobody ends up with two copies. The regression test fails against the pre-fix loop and passes after it. I got this wrong in #624 by asserting a negative from a summarized fetch of the docs page, which rendered `skill(s)` as `skills`. The binary is the source of truth here.
jeremy added a commit
that referenced
this pull request
Aug 22, 2026
…or-roundtrip * origin/main: (96 commits) ci: bump the github-actions group with 6 updates (#639) Reject three more doomed invocations before draining stdin (#645) Stdin `-` support everywhere sensible; usage error for stray `-` elsewhere (#641) Add hey-cli Windows signing secrets to the release env manifest (#642) deps: bump the go-dependencies group with 5 updates (#638) Update nix flake and plugin version for v0.9.1 ci: bump the github-actions group with 4 updates (#633) Add basecamp files replace: publish a new version of an uploaded file (#634) Add basecamp files versions — HELD, blocked on the SDK (#622) Update nix flake and plugin version for v0.9.0 Make the Codex probe's timeout actually bound doctor (#629) Make the lockstep check catch stale agreement and .yaml workflows (#628) Keep refreshing opencode's other spelling (#627) Lint the release the same way we lint everything else (#625) Install the skill where opencode actually looks (#624) Take the communiques out of the source tree (#623) Correct the API coverage claim: 183/184, not 100% (#621) Stop echoing back step fields the caller never changed (#620) Drive the circuit breaker's clock from tests, not sleep() (#619) Tell agents the truth about card column moves (#618) ...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes part of #617.
skillLocationsoffered OpenCode targets atskill/, singular. opencode readsskills/, plural — it has never read either path we wrote.{Name: "OpenCode (Global)", Path: "~/.config/opencode/skill/basecamp/SKILL.md"}, {Name: "OpenCode (Project)", Path: ".opencode/skill/basecamp/SKILL.md"},Why this failed silently, twice
That list is both the wizard's install targets and the refresh set, so one typo broke two things:
basecamp skillwrote a file opencode would never load, then reported success.refreshAllInstalledSkillsonly visits paths in this list and skips ones that don't exist. An opencode user who put the skill at the plural path by hand never got it refreshed on upgrade.Verification
Real binaries, temp
HOME, staleSKILL.mdpre-placed at~/.config/opencode/skills/basecamp/:origin/mainSTALE~/.agents/skills/basecamp/SKILL.mdis refreshed by both, which is the next point.The skill already worked in opencode
opencode also searches
~/.agents/skills/<name>/SKILL.md— the canonical targetinstallSkillFileshas always written. So this fixes the wizard and the refresh loop, not first-run coverage. Nobody was unable to use the skill in opencode; some people were told they'd installed it somewhere it wasn't.About the test
The existing refresh test built its opencode path from the same wrong spelling the code used, so it asserted the bug was working. The new
TestSkillLocationsMatchAgentSearchPathspins the literals instead of deriving them, so a test can't mirror the typo again.Not in this PR
#617 also raises opencode plugin parity with what Codex got in #550 — hooks, not just a skill. opencode plugins are JS/TS modules in
.opencode/plugins/or npm packages named inopencode.json: a different mechanism from both existing manifests, and a new artifact for this repo to build, version-stamp and ship. That wants a decision before it wants code, so it stays out of here. The path fix may well be all #617 actually needs.Frontmatter needs no change — opencode wants
name+descriptionwithnamematching the directory, whichskills/basecamp/SKILL.mdalready satisfies.Search paths confirmed at https://opencode.ai/docs/skills/.
bin/cigreen.Summary by cubic
Fixes the OpenCode skill install and refresh paths to use
skills/so OpenCode actually loads the file; the wizard and refresh loop now work as expected. Part of #617.skillLocationsfor OpenCode (Global/Project) fromskill/toskills/.TestSkillLocationsMatchAgentSearchPathsto pin literal paths.Written for commit 3176e94. Summary will update on new commits.