From yoe
Pulls Alpine Linux packages through module‑alpine instead of writing from‑source units. Useful for cross toolchains, niche build tools, or language runtimes that Alpine already packages.
How this skill is triggered — by the user, by Claude, or both
Slash command
/yoe:pulling-alpine-packagesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
When a build wants something Alpine `main` or `community` ships, pull it through
When a build wants something Alpine main or community ships, pull it through
module-alpine rather than writing a from-source unit. This is the default; a
from-source unit is the fallback when Alpine doesn't ship the package or ships
the wrong version.
module-alpine exposes Alpine's repos as feeds, not per-package files. One
alpine_feed(...) call per repo section registers a synthetic module
(alpine.main, alpine.community) backed by a checked-in APKINDEX. Every
package in that index is available; the unit for a package materializes
lazily the first time a build's closure references it. You do not generate a
.star file to consume a package — you just name it.
armv7-R from
aarch64 — BeaglePlay's R5 SPL pulls gcc-arm-none-eabi,
binutils-arm-none-eabi, newlib-arm-none-eabi).Do not use this for components where we want git-source tracking and the
yoe dev patch workflow (kernels, U-Boot, OP-TEE, project libraries, anything
likely to need local patches), nor where the build is the product (toolchain,
busybox, base-files, init).
In the common case there is nothing to generate and nothing to push — the feed already exposes the package.
Name the package in deps. Add the Alpine package name directly to the
consuming unit's deps (build-time) and/or runtime_deps. The synthetic
feed module resolves it lazily; its apk data segment is extracted into
$DESTDIR and thus the consumer's /build/sysroot/. Binaries land on the
default /build/sysroot/usr/bin PATH.
deps = [
"toolchain-musl",
"gcc-arm-none-eabi", # ← resolved from alpine.community, lazily
"binutils-arm-none-eabi",
"newlib-arm-none-eabi",
]
No prefer_modules entry is needed when the package exists only in the
feed: synthetic modules always rank below every real module, so a feed
package with no source-unit competitor resolves automatically.
Only override with prefer_modules when a source unit also claims the
name. If module-core builds xz from source but a particular image needs
Alpine's prebuilt xz (e.g. for a shared liblzma.so.5 soversion), route it
in PROJECT.star. The map is keyed by distro:
prefer_modules = {
"alpine": {
"xz": "alpine.main",
"curl": "alpine.main",
},
}
Without an entry, the from-source unit wins. Reach for this only to flip a specific package to the feed, and leave a comment explaining why (the e2e project's PROJECT.star has worked examples).
testing is never available. Only main and community are wrapped.
The checked-in APKINDEX pins a point release. If you need a package version
Alpine has since published (a security bump, a new package), the APKINDEX must
be refreshed in the module-alpine repo:
yoe update-feeds # run in the module-alpine repo root
git diff feeds/ # spot-check version bumps / new packages
yoe update-feeds fetches each feed's APKINDEX.tar.gz, verifies the RSA
signature against the feed's keys=[...], and atomically rewrites
feeds/<section>/<arch>/APKINDEX. It writes only — it does not stage, commit,
or push.
The live module-alpine checkout is under
testdata/<project>/cache/modules/module-alpine/ (for test builds,
testdata/e2e-project/cache/modules/module-alpine/). Any change there — a
refreshed APKINDEX, a new *-enable.star companion — must be committed and
pushed upstream: the next yoe build does
git fetch && git checkout FETCH_HEAD in the cache and silently discards
uncommitted or un-pushed local edits. Pause and confirm the push landed before
re-running anything that triggers a module sync. Never do the upstream
commit/push yourself — the user manages those repos.
A feed gives you the .apk but does not enable init scripts — Alpine ships them
disabled. To enable a service, add a one-line companion unit
(<svc>-enable.star) in module-alpine that depends on the package's -openrc
unit and sets services = [...] to bake the runlevel symlink. Do not scan the
rootfs for init scripts; explicit companion units are how a package's services
become enabled. (This is module-alpine repo work — same commit-and-push rule as
above.)
BeaglePlay's R5 SPL is Cortex-R5F (armv7-R), an ISA the aarch64 build container
can't emit. Instead of building an entire cross toolchain from source, the SPL
unit lists Alpine's gcc-arm-none-eabi, binutils-arm-none-eabi, and
newlib-arm-none-eabi in deps. No file generated, no Dockerfile change, no
source build, no maintenance — the community feed materializes those three units
on demand.
.star file to consume a package. Not needed — the feed
exposes every main/community package lazily. Just name it in deps.
(Maintaining module-alpine itself — refreshing the checked-in APKINDEX after
Alpine ships a release — is yoe update-feeds run in that repo, not anything
a consuming project does.)prefer_modules entry for a feed-only package. Unnecessary —
synthetics already lose to real modules, so a package with no source-unit
competitor resolves without routing. Use prefer_modules only to override a
source unit with the feed's build.yoe update-feeds or adding a companion. A
local-only commit in the cache survives exactly until the next yoe build's
module sync, then vanishes.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub yoebuild/yoe --plugin yoe