From resyndeo
Use when the user wants to package an app they're building as a Resyndeo plugin and run it on their own fleet — "publish this as a resyndeo plugin", "deploy my app to my cluster", "turn this repo into a plugin", "package this app as a Resyndeo plugin", "publish my service to my fleet", "deploy my own app to my cluster". Drives author → docker build → k3d import → publish via the resyndeo CLI.
How this skill is triggered — by the user, by Claude, or both
Slash command
/resyndeo:publish-resyndeo-pluginThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill packages a local app as a private Resyndeo plugin and deploys it to
This skill packages a local app as a private Resyndeo plugin and deploys it to the user's own fleet. The CLI handles the full build→import→publish pipeline; this skill drives that workflow step by step.
Reference material (pull when you need detail):
references/rail-reference.md — full plugin.yaml field guidereferences/capability-kinds.md — backing-service capability kinds and the env vars they injectexamples/http-service/ — minimal HTTP server pluginexamples/postgres-api/ — plugin that consumes a Postgres backing serviceVerify the environment before touching any files.
resyndeo whoami # must print an email; if not → resyndeo login
docker info # must succeed; if not, start Docker
resyndeo cluster list # must list ≥1 cluster; if not → resyndeo cluster install
All three must pass before continuing.
plugin init writes plugin.yaml, Dockerfile, and .dockerignore with sane
defaults. It refuses to run only when plugin.yaml already exists — it does
not guard Dockerfile/.dockerignore. So if plugin.yaml is absent but the
directory already has a Dockerfile (common — you're packaging an app you've
already built), init will silently overwrite that Dockerfile with the
generic scaffold.
Check what's already there before running it:
ls plugin.yaml Dockerfile .dockerignore 2>/dev/null
plugin.yaml and no Dockerfile you care about → safe to scaffold:
resyndeo plugin init <slug> # e.g. resyndeo plugin init my-api
Dockerfile (or .dockerignore) you want to keep → do not run
init; it would clobber them. Hand-write plugin.yaml instead (schema in
references/rail-reference.md) and leave your Dockerfile untouched.plugin.yaml already exists → init errors and changes nothing; just
edit the existing plugin.yaml.Then edit plugin.yaml using the actual app's values:
workload.ports[].port to the port the app listens on (e.g. 8080).capabilities.consumes — see references/capability-kinds.md for the list of
valid kind values and the env vars each one injects.metadata.title, metadata.description (required — backend rejects
empty), metadata.category, and metadata.version.Do not set workload.image — the publish command computes and injects it.
See references/rail-reference.md for the full field guide.
workload.ports[].port.capabilities.consumes is declared, the platform injects connection env
vars once both plugins are deployed (e.g. DATABASE_URL for Postgres). The app
must read those env-var names — do not hard-code connection strings.examples/ for minimal working examples.workload.image to plugin.yaml — publish owns that field.Before publishing, verify the image builds cleanly:
docker build -t tmp-check .
# Optionally smoke-test it locally:
docker run --rm -p 8080:8080 tmp-check
Fail early here rather than after publish.
resyndeo plugin publish <dir> --deploy
# e.g. resyndeo plugin publish . --deploy
The CLI:
plugin.yaml, extracts slug + version.docker build with that tag.k3d image import
(so imagePullPolicy: IfNotPresent resolves without a registry).workload.image into the rail and POSTs it to the backend, which
registers it as a private catalog plugin owned by you.--deploy: immediately installs the plugin to your cluster.Expected output:
→ building resyndeo-local/<prefix>-<slug>:<version>...
✓ built resyndeo-local/<prefix>-<slug>:<version>
✓ imported into 1 cluster(s)
✓ published <slug> → your catalog (private)
✓ <slug> deploying
resyndeo plugin status <slug> # → "installed" once the pod is Running
To update: bump metadata.version in plugin.yaml (the same version will not
roll a running pod), then re-run resyndeo plugin publish . --deploy.
To remove:
resyndeo plugin delete <slug>
plugin publish imports the image into clusters on the local machine only.
A remote cluster added later, or a second machine, will see ImagePullBackOff
because it cannot pull a local image. Workaround: re-publish from that machine,
or push to a registry the remote cluster can reach (future feature).
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 syndeo-ai/resyndeo-claude-plugin --plugin resyndeo