Skip to content

Install the skill where opencode actually looks - #624

Merged
jeremy merged 1 commit into
mainfrom
fix/opencode-skill-path
Aug 5, 2026
Merged

Install the skill where opencode actually looks#624
jeremy merged 1 commit into
mainfrom
fix/opencode-skill-path

Conversation

@jeremy

@jeremyjeremy commented Aug 5, 2026

Copy link
Copy Markdown
Member

Closes part of #617.

skillLocations offered OpenCode targets at skill/, singular. opencode reads skills/, 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:

  • The wizard. Picking "OpenCode (Global)" in basecamp skill wrote a file opencode would never load, then reported success.
  • The refresh loop.refreshAllInstalledSkills only 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, stale SKILL.md pre-placed at ~/.config/opencode/skills/basecamp/:

BuildThat file after a run
origin/mainstill reads STALE
this branchbyte-identical to the embedded skill

~/.agents/skills/basecamp/SKILL.md is refreshed by both, which is the next point.

The skill already worked in opencode

opencode also searches ~/.agents/skills/<name>/SKILL.md — the canonical target installSkillFiles has 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 TestSkillLocationsMatchAgentSearchPaths pins 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 in opencode.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 + description with name matching the directory, which skills/basecamp/SKILL.md already satisfies.

Search paths confirmed at https://opencode.ai/docs/skills/. bin/ci green.


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.

  • Bug Fixes
    • Update skillLocations for OpenCode (Global/Project) from skill/ to skills/.
    • Add TestSkillLocationsMatchAgentSearchPaths to pin literal paths.
    • Update the refresh test to use the plural OpenCode path.

Written for commit 3176e94. Summary will update on new commits.

Review in cubic

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/
CopilotAI balanced review requested due to automatic review settings August 5, 2026 08:31
@github-actionsgithub-actionsBot added commands CLI command implementations tests Tests (unit and e2e) labels Aug 5, 2026
@jeremyjeremy mentioned this pull request Aug 5, 2026
CopilotAI reviewed Aug 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@jeremy
jeremy merged commit 7aac5fd into mainAug 5, 2026
24 of 25 checks passed
@jeremy
jeremy deleted the fix/opencode-skill-path branch August 5, 2026 08:35
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)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commandsCLI command implementationstestsTests (unit and e2e)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jeremy