Files
opencode-devbox/docs/omos-skills.md
T
Joakim Persson ba8000732d
Validate / base-change-warning (push) Successful in 7s
Validate / docs-check (push) Successful in 13s
Publish Docker Image / base-decide (push) Successful in 8s
Publish Docker Image / resolve-versions (push) Successful in 10s
Validate / validate-omos (push) Successful in 4m15s
Validate / validate-base (push) Successful in 5m2s
Publish Docker Image / build-base (push) Successful in 30m33s
Publish Docker Image / smoke-base (push) Successful in 3m20s
Publish Docker Image / smoke-omos (push) Successful in 4m24s
Publish Docker Image / build-variant-base (push) Successful in 13m37s
Publish Docker Image / build-variant-omos (push) Successful in 30m18s
Publish Docker Image / update-description (push) Successful in 6s
Publish Docker Image / promote-base-latest (push) Successful in 14s
v2.1.0: symlink OMOS bundled skills from image, bump opencode 1.17.4->1.17.5
Deploy the five oh-my-opencode-slim bundled skills (clonedeps, codemap,
deepwork, oh-my-opencode-slim, simplify) by symlinking them from the image
path into ~/.agents/skills/ on every container start, instead of the
installer copying them into the persistent config volume on first run only.
Image-sourced links mean 'docker compose pull' + recreate refreshes the
skills with no installer run and no config reset; the old copy-on-first-run
froze them in the volume forever.

- entrypoint-user.sh: new non-fatal OMOS bundled-skills reconcile block
  (runs after skillset deploy so OMOS wins the simplify collision; absolute
  symlinks; gated by OMOS_SKILLS, now independent of ENABLE_OMOS). Both
  installer calls now pass --skills=no. One-time migration backs up (never
  deletes) frozen real copies in ~/.config/opencode/skills/ to .bak.<epoch>.
- scripts/smoke-test.sh: assert the bundled-skills source path on omos.
- Bump OPENCODE_VERSION 1.17.4 -> 1.17.5.
- Versioning: document the move to independent image semver (v2.0.0 was the
  decouple point), mirroring pi-devbox. README/AGENTS/.env.example/CHANGELOG
  updated; new docs/omos-skills.md.
2026-06-13 22:32:09 +02:00

5.3 KiB

OMOS bundled skills

How the five skills bundled with oh-my-opencode-slim (OMOS) are deployed in this image, why the mechanism changed, and how to keep them up to date.

TL;DR

  • OMOS bundles five skills: clonedeps, codemap, deepwork, oh-my-opencode-slim, simplify.
  • They are symlinked from the image into ~/.agents/skills/ on every container start by entrypoint-user.sh (gated by OMOS_SKILLS, default true).
  • To update them, pull a newer image and recreate the container — no installer run, no config reset:
    docker compose pull
    docker compose up -d --force-recreate
    

Why it works this way

The skills ship inside the OMOS npm package, baked into the image at /usr/lib/node_modules/oh-my-opencode-slim/src/skills/<name>/. On start the entrypoint creates one absolute symlink per skill into ~/.agents/skills/ — the same flat directory the skillset deploy uses and which opencode scans (directly and via the ~/.claude/skills pointer).

Because the symlink target lives in the image, not in a volume, the skill content tracks whatever image you run. Pull a newer *-omos image and the skills update on the next container start. ~/.agents/skills/ is itself an ephemeral container-layer directory rebuilt from scratch on every start, so the reconcile is idempotent and self-healing.

The symlinks are absolute (unlike skillset's relative links): the target is always inside the container at a fixed /usr path, so there is no host/container path divergence to guard against.

The old mechanism (and the trap it created)

Previously the OMOS installer (oh-my-opencode-slim install --skills=yes) copied the skills into ~/.config/opencode/skills/ — but only on the very first container start, gated by the absence of oh-my-opencode-slim.json. That directory is the persistent devbox-opencode-config named volume.

The consequence: once the config existed, the installer was skipped forever, so the copied skills froze at whatever the image shipped on first run. Pulling a newer image did nothing (the copies lived in the volume, not the image). The only refresh path was OMOS_RESET=true, which runs install --reset and also overwrites your hand-tuned opencode.jsonc (model choices, agent config). Updating skills meant clobbering unrelated config — a bad trade.

The installer has no skills-only refresh flag (--skills=yes|no is all-or- nothing within a full install; --reset overwrites everything), so the fix was to stop using the installer for skills entirely. The two install invocations in entrypoint-user.sh now pass --skills=no; the installer manages only the agent config (oh-my-opencode-slim.json).

One-time migration of frozen copies

Existing volumes still contain the old frozen real directories under ~/.config/opencode/skills/. Because opencode prefers a name found there over the same name in ~/.agents/skills/, those stale copies would shadow the fresh image-sourced symlinks. On the first start after upgrading, the entrypoint backs each of them up — never deletes — to ~/.config/opencode/skills/<name>.bak.<epoch> and writes a marker at ~/.config/opencode/.omos-skills-migrated so the migration runs exactly once. Only real directories are touched; any symlink in that directory is left alone.

If everything looks right after a few sessions, the backups are safe to remove:

rm -rf ~/.config/opencode/skills/*.bak.*

Relationship to skillset

The skillset repo deploys its own version-controlled skills into ~/.agents/skills/ via deploy-skills.sh --bootstrap --prune-stale, which the entrypoint runs on every start — before the OMOS reconcile. If a skill name exists in both, OMOS wins: the reconcile uses ln -sfn, which replaces any existing symlink. Today the only overlap is simplify (the OMOS copy is richer — it bundles codemap.md and a README.md), so simplify was removed from the skillset repo and the image copy owns the name.

Configuration

Variable Default Effect
OMOS_SKILLS true Symlink the bundled skills into ~/.agents/skills/ on each start. Set false to deploy no skills from the image.

OMOS_SKILLS is independent of ENABLE_OMOS: the skills are useful to plain opencode even when the multi-agent orchestration config is not enabled. The reconcile is additionally gated on the bundled-skills source being present, so it is automatically a no-op on the non-OMOS (base) image variant.

Troubleshooting

  • A skill didn't update after docker compose pull. Make sure you recreated the container (docker compose up -d --force-recreate); a plain restart reuses the old container layer. Confirm the link target — readlink ~/.agents/skills/deepwork should point under /usr/lib/node_modules/oh-my-opencode-slim/src/skills/.
  • A skill disappeared. If OMOS upstream restructured its package the symlink target may no longer exist. The build-time smoke test asserts the source path, so this should be caught in CI; if you hit it at runtime, look for a dangling link in ls -l ~/.agents/skills/.
  • I want a frozen copy back. It's at ~/.config/opencode/skills/<name>.bak.<epoch> until you delete it.