From 7587a13aaee09db1d29cbda84209f444edd4613a Mon Sep 17 00:00:00 2001 From: "dylan.wang" Date: Fri, 25 Sep 2026 17:28:59 +0800 Subject: [PATCH] skill: top-level clawdis and an Agent Plugins manifest for v1.0.1 awesome-copilot's intake reads a plugin's manifest from .github/plugin/, .plugin/ or the repository root, and lints SKILL.md with vally 0.12.0, which refuses a metadata value that is not a string. v1.0.0 fails both: its only manifest is .claude-plugin/plugin.json, and the declarations for OpenClaw and ClawHub sit in a nested metadata.openclaw. - Move those declarations, unchanged, to a top-level clawdis block, which ClawHub reads the same way. OpenClaw no longer sees them; the compatibility field and the skill's first step still name and check python3 and git. - Add plugin.json at the root: the Claude Code manifest plus the Agent Plugins 1.0 $schema, for Copilot CLI, VS Code and awesome-copilot. - check-versions.sh compares the two manifests field for field, so the version is now written in four places. - Bump to 1.0.1, the release to submit to awesome-copilot. - ADR-026 records why; ADR-024, ADR-025, publishing.md and the READMEs follow it. Co-Authored-By: Claude Opus 5.5 --- .claude-plugin/plugin.json | 2 +- .github/scripts/check-versions.sh | 22 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 2 +- README.zh-CN.md | 2 +- docs/decisions/024-one-command-install.md | 38 ++++---- .../025-site-in-its-own-repository.md | 5 +- ...atter-and-manifests-for-awesome-copilot.md | 96 +++++++++++++++++++ docs/publishing.md | 82 ++++++++++------ plugin.json | 14 +++ skills/envrelay/SKILL.md | 34 +++---- tests/installer.sh | 8 +- 13 files changed, 233 insertions(+), 76 deletions(-) create mode 100644 docs/decisions/026-frontmatter-and-manifests-for-awesome-copilot.md create mode 100644 plugin.json diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index b9beda8..35d14a1 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "envrelay", - "version": "1.0.0", + "version": "1.0.1", "description": "Move a development environment to a new machine: back up dotfiles, credentials, git repositories, AI coding agent state and installed software into one passphrase-encrypted file, then restore it step by step.", "author": { "name": "FutrixDev", diff --git a/.github/scripts/check-versions.sh b/.github/scripts/check-versions.sh index e9a4bc7..462be76 100755 --- a/.github/scripts/check-versions.sh +++ b/.github/scripts/check-versions.sh @@ -7,8 +7,11 @@ # (metadata.version in SKILL.md) picks the release its install.sh fetches, so a # skill installed from anywhere gets the binary it was written for. The Claude # Code plugin's (.claude-plugin/plugin.json) is what /plugin compares to decide -# whether there is an update. With TAG, the tag must be v as well. -# envrelay.com names the version too, in its own repository (ADR-025). +# whether there is an update. plugin.json at the root is the same manifest for +# Copilot CLI, VS Code and awesome-copilot, in the Agent Plugins format +# (ADR-026), so it must match the Claude Code one field for field. With TAG, the +# tag must be v as well. envrelay.com names the version too, in its +# own repository (ADR-025). set -eu root=$(git -C "$(dirname "$0")" rev-parse --show-toplevel) @@ -44,6 +47,21 @@ esac plugin=$(python3 -c 'import json, sys; print(json.load(open(sys.argv[1]))["version"])' .claude-plugin/plugin.json) [ "$plugin" = "$version" ] || fail ".claude-plugin/plugin.json has version $plugin, Cargo.toml has $version" +# The Agent Plugins manifest is the Claude Code one plus the $schema that opts +# it into that format. +agent=$(python3 - plugin.json .claude-plugin/plugin.json <<'EOF' +import json, sys +schema = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" +agent, claude = (json.load(open(path)) for path in sys.argv[1:]) +if agent.pop("$schema", None) != schema: + print(f'plugin.json must have "$schema": "{schema}"') +differ = sorted(k for k in agent.keys() | claude.keys() if agent.get(k) != claude.get(k)) +if differ: + print("plugin.json and .claude-plugin/plugin.json differ in " + ", ".join(differ)) +EOF +) +[ -z "$agent" ] || fail "$agent" + if [ $# -gt 0 ] && [ "$1" != "v$version" ]; then fail "tag $1 does not match Cargo.toml's version: expected v$version" fi diff --git a/Cargo.lock b/Cargo.lock index 65867f6..7d52169 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -424,7 +424,7 @@ dependencies = [ [[package]] name = "envrelay" -version = "1.0.0" +version = "1.0.1" dependencies = [ "age", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index da555ab..42a1223 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "envrelay" -version = "1.0.0" +version = "1.0.1" edition = "2024" rust-version = "1.97.0" license = "MIT OR Apache-2.0" diff --git a/README.md b/README.md index 3181052..9c9dc19 100644 --- a/README.md +++ b/README.md @@ -229,7 +229,7 @@ sh .github/scripts/check-versions.sh ## Releasing -1. Set the new version in `Cargo.toml`, in `metadata.version` in [`skills/envrelay/SKILL.md`](skills/envrelay/SKILL.md) and in [`.claude-plugin/plugin.json`](.claude-plugin/plugin.json), and run `cargo build` so `Cargo.lock` follows. CI fails until the three agree. +1. Set the new version in `Cargo.toml`, in `metadata.version` in [`skills/envrelay/SKILL.md`](skills/envrelay/SKILL.md), in [`.claude-plugin/plugin.json`](.claude-plugin/plugin.json) and in [`plugin.json`](plugin.json), and run `cargo build` so `Cargo.lock` follows. CI fails until the four agree. 2. Once that is merged, tag the merge commit on GitHub's main and push the tag right away (until the release exists, a skill installed from main asks for a release that is not there yet), for example: ```bash diff --git a/README.zh-CN.md b/README.zh-CN.md index b68de7d..19d6e72 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -229,7 +229,7 @@ sh .github/scripts/check-versions.sh ## 发版 -1. 在 `Cargo.toml`、[`skills/envrelay/SKILL.md`](skills/envrelay/SKILL.md) 的 `metadata.version`、[`.claude-plugin/plugin.json`](.claude-plugin/plugin.json) 三处改成新版本号,再跑一次 `cargo build` 让 `Cargo.lock` 跟上。三处不一致时 CI 会失败。 +1. 在 `Cargo.toml`、[`skills/envrelay/SKILL.md`](skills/envrelay/SKILL.md) 的 `metadata.version`、[`.claude-plugin/plugin.json`](.claude-plugin/plugin.json)、[`plugin.json`](plugin.json) 四处改成新版本号,再跑一次 `cargo build` 让 `Cargo.lock` 跟上。四处不一致时 CI 会失败。 2. 合并之后,马上给 GitHub 上 main 的合并提交打 tag 并推送(release 出来之前,从 main 装的 skill 会去找一个还不存在的 release),例如: ```bash diff --git a/docs/decisions/024-one-command-install.md b/docs/decisions/024-one-command-install.md index 7759c40..9035b1d 100644 --- a/docs/decisions/024-one-command-install.md +++ b/docs/decisions/024-one-command-install.md @@ -3,7 +3,8 @@ Date: 2026-09-24 Status: accepted Extends: ADR-022 (deterministic mechanics scripts) -Amended by: ADR-025 (the site moves to a repository of its own) +Amended by: ADR-025 (the site moves to a repository of its own), ADR-026 +(frontmatter and manifests that awesome-copilot accepts) ## Context @@ -101,15 +102,16 @@ step: it shows the user the `--dry-run` plan, says what `envrelay` is, and runs `install.sh --bin-only` only on a yes. Installing the passphrase layer is the user's decision, like every other install the skill proposes. -**One version, written in three places.** `Cargo.toml` (what `envrelay +**One version, written in four places.** `Cargo.toml` (what `envrelay --version` prints), `metadata.version` in SKILL.md (which release the skill's -installer fetches) and `.claude-plugin/plugin.json` (what Claude Code compares -to offer an update). `.github/scripts/check-versions.sh` fails CI and the -release preflight unless they agree. It asks the installer which release it -would fetch rather than reading SKILL.md a second way, so the check and the -user's path share one parser. The homepage's badge and demo name the version -too, from a meta tag that the site's repository sets after each release -(ADR-025). +installer fetches), `.claude-plugin/plugin.json` (what Claude Code compares to +offer an update) and `plugin.json` at the root (the same manifest for Copilot +CLI, VS Code and awesome-copilot, ADR-026). `.github/scripts/check-versions.sh` +fails CI and the release preflight unless they agree. It asks the installer +which release it would fetch rather than reading SKILL.md a second way, so the +check and the user's path share one parser. The homepage's badge and demo name +the version too, from a meta tag that the site's repository sets after each +release (ADR-025). That is what makes a skill installed from anywhere safe. Run from inside an installed skill, `install.sh` fetches the release matching the `SKILL.md` @@ -125,13 +127,14 @@ the latest release. - `allowed-tools: Bash(python3 ${CLAUDE_SKILL_DIR}/scripts/*)` pre-approves the scripts and nothing else. The installer and `envrelay` stay behind a prompt. - `compatibility` names what the skill needs to run. -- `metadata.openclaw` declares the required binaries (python3, git), the - operating systems (darwin, linux), the two optional environment variables - the installer reads, and the homepage. OpenClaw decides from these whether - the skill can load, and ClawHub's review compares them with what the code - does. The Agent Skills spec expects `metadata` to map strings to strings; - OpenClaw documents this nested shape, and no validator we have found - rejects it. +- A top-level `clawdis` block declares the required binaries (python3, git), + the operating systems (darwin, linux), the two optional environment + variables the installer reads, and the homepage, and ClawHub's review + compares them with what the code does. v1.0.0 had them in + `metadata.openclaw`, where OpenClaw itself also read them to decide whether + the skill can load. They moved because awesome-copilot's lint refuses a + `metadata` value that is not a string. OpenClaw does not read the new block + (ADR-026). - There is no `license` field. ClawHub releases every skill it publishes under MIT-0 and asks for no conflicting license terms in SKILL.md, so the field would be wrong there. The repository's MIT OR Apache-2.0 covers the source, @@ -216,7 +219,8 @@ Smithery, GitHub's awesome-copilot, the directories that crawl GitHub, and the awesome lists. `docs/publishing.md` is the checklist, with what each one asks for and why some are left out. The repository is also a plugin marketplace of its own (`.claude-plugin/`), which Claude Code, GitHub Copilot CLI and VS Code -read. +read; the last two take the plugin's manifest from the root `plugin.json` +(ADR-026). `gh skill publish` is used only as `--dry-run`, plus the `agent-skills` repo topic it would otherwise add. Without `--dry-run` it creates a GitHub release diff --git a/docs/decisions/025-site-in-its-own-repository.md b/docs/decisions/025-site-in-its-own-repository.md index 18bbc66..031f6c4 100644 --- a/docs/decisions/025-site-in-its-own-repository.md +++ b/docs/decisions/025-site-in-its-own-repository.md @@ -3,6 +3,7 @@ Date: 2026-09-25 Status: accepted Amends: ADR-024 (one command installs the binary and the skill) +Amended by: ADR-026 (frontmatter and manifests that awesome-copilot accepts) ## Context @@ -37,8 +38,8 @@ installed pointed at it. follows this repository's release workflow. It needs nothing from the site's repository: it compares what envrelay.com serves with the release's `install.sh`, byte for byte, then installs through the one-liner. -- **The version is written in three places here**: `Cargo.toml`, SKILL.md's - `metadata.version` and `.claude-plugin/plugin.json`, which +- **The version is written in four places here**: `Cargo.toml`, SKILL.md's + `metadata.version`, and the plugin's two manifests since ADR-026, which `check-versions.sh` compares. The homepage keeps its `envrelay-version` meta, which a maintainer sets in the site's repository once a release is out, and deploys. diff --git a/docs/decisions/026-frontmatter-and-manifests-for-awesome-copilot.md b/docs/decisions/026-frontmatter-and-manifests-for-awesome-copilot.md new file mode 100644 index 0000000..fb616a8 --- /dev/null +++ b/docs/decisions/026-frontmatter-and-manifests-for-awesome-copilot.md @@ -0,0 +1,96 @@ +# ADR-026: Frontmatter and manifests that awesome-copilot accepts + +Date: 2026-09-25 +Status: accepted +Amends: ADR-024 (one command installs the binary and the skill), ADR-025 (the +site moves to a repository of its own) + +## Context + +github/awesome-copilot lists a plugin that lives in its own repository once an +issue form names a release tag, its commit and a version. Their intake +(`eng/external-plugin-quality-gates.mjs`, which pins `@microsoft/vally` 0.12.0 +and Ajv 8.20.0) checks out that commit, then: + +- reads the plugin's manifest with `git show` from `.github/plugin/plugin.json`, + `.plugin/plugin.json` or `plugin.json` at the root, the first that exists, + and stops if there is none; +- requires the manifest's `version` to be the one submitted; +- runs `vally lint` over the skills directories the manifest names, or over the + whole repository when it names none; +- installs the plugin with Copilot CLI from a marketplace it makes on the spot, + and checks that the manifest arrived; +- checks the manifest against the Agent Plugins 1.0 specification, whose top + level allows `$schema`, `name`, `version`, `description`, `author`, + `homepage`, `repository`, `license`, `keywords` and `extensions`. + +v1.0.0 fails at the first step: its one manifest is +`.claude-plugin/plugin.json`, which Claude Code reads and the intake does not. +It would fail the lint too. vally refuses a SKILL.md `metadata` value that is +not a string ("Metadata values must be strings. Non-string values found for +key(s): openclaw"), and ADR-024 put the declarations for OpenClaw and ClawHub +in a nested `metadata.openclaw`. + +Each reader of those declarations looks in a place of its own: + +- ClawHub (`convex/lib/skills/index.ts`) takes `metadata.clawdbot`, + `metadata.clawdis` or `metadata.openclaw` if it is an object, and otherwise a + top-level `clawdis` block. +- OpenClaw (`packages/markdown-core/src/frontmatter.ts` and + `src/shared/frontmatter.ts`) turns `metadata` into JSON text, parses it back + and takes an `openclaw` or `clawdbot` object from it. It reads no other + field for these. +- vally, `gh skill` and `claude plugin validate --strict` accept extra + top-level fields. `skills-ref`, the Agent Skills reference validator, + refuses them. + +No one frontmatter satisfies all of these. + +## Decision + +- **The declarations move to a top-level `clawdis` block**, unchanged: the + required binaries, the operating systems, the two optional environment + variables and the homepage. `metadata` keeps only `version`. +- **`plugin.json` at the root is the plugin's Agent Plugins manifest**: the + Claude Code one plus the `$schema` that opts into Agent Plugins 1.0. Copilot + CLI and VS Code read it with that format's semantics, and it is where + awesome-copilot finds it. Claude Code reads only + `.claude-plugin/plugin.json`, where it ignores `$schema`, so that file + stays. +- **`check-versions.sh` compares the two manifests** field for field, apart + from `$schema`. The version is now written in four places. +- **v1.0.1 is the release to submit.** + +## Consequences + +- vally passes over the whole repository, and the manifest has no field the + specification check warns about. +- ClawHub reads the same values from v1.0.1 as from v1.0.0. +- **OpenClaw no longer sees the declarations.** It used them to decide whether + the skill can load; now it loads the skill on Windows too, or where python3 + or git is missing, and knows no homepage for it. The `compatibility` field + still names macOS or Linux, python3 and git, and the skill's first step, + "Before anything: the tools", checks for python3 and git before a backup or + a restore starts. +- `skills-ref validate` fails on `clawdis`. No channel we submit to is known to + run it. +- Another manifest in `.github/plugin/` or `.plugin/` would take over from the + root one at awesome-copilot's intake, and Copilot CLI's documented lookup + checks `.plugin/plugin.json` first as well (`docs/publishing.md`, section 2). + +## Alternatives rejected + +- **Keep `metadata.openclaw` and leave out awesome-copilot.** OpenClaw would + keep hiding the skill where it cannot run, but the owner chose the listing: + awesome-copilot is the marketplace that Copilot CLI and VS Code ship with. +- **Declare nothing.** ClawHub's review would see an installer that downloads + a binary, and nothing declared to compare it with. +- **`metadata.openclaw` as a JSON string.** vally would accept it, but ClawHub + and OpenClaw both take only an object there. +- **A symlink from the root to `.claude-plugin/plugin.json`.** `git show` + returns the link's target path, not the manifest. +- **The manifest in `.github/plugin/` or `.plugin/`.** Those are the older + locations; Agent Plugins 1.0, which Copilot CLI, VS Code and Cursor load, + puts the manifest at the plugin's root. +- **The root manifest alone.** Claude Code reads only + `.claude-plugin/plugin.json`. diff --git a/docs/publishing.md b/docs/publishing.md index 2e40da5..83b172e 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -125,30 +125,35 @@ of its own ([ADR-025](decisions/025-site-in-its-own-repository.md)). ### The repository's own plugin marketplace -`.claude-plugin/marketplace.json` makes the repository a plugin marketplace, -and `.claude-plugin/plugin.json` describes its one plugin. It works as soon as -the repository is public, and the README lists it. +`.claude-plugin/marketplace.json` makes the repository a plugin marketplace +with one plugin, which two manifests describe with the same fields: +`.claude-plugin/plugin.json` for Claude Code, and `plugin.json` at the root, in +the [Agent Plugins](https://agent-plugins.org/) format, for GitHub Copilot CLI, +VS Code and awesome-copilot +([ADR-026](decisions/026-frontmatter-and-manifests-for-awesome-copilot.md)). It +works as soon as the repository is public, and the README lists it. - Claude Code: `/plugin marketplace add FutrixDev/envrelay-skill`, then `/plugin install envrelay@envrelay`. -- GitHub Copilot CLI reads the same files: `copilot plugin marketplace add +- GitHub Copilot CLI reads the same marketplace: `copilot plugin marketplace add FutrixDev/envrelay-skill`, then `copilot plugin install envrelay@envrelay`. - VS Code's agent plugins read it when the repository is added to the `chat.plugins.marketplaces` setting. Factory Droid falls back to `.claude-plugin/marketplace.json` as well (its commands were not checked). Validate before every release; it passes with no errors or warnings as of -v1.0.0: +v1.0.1: ```bash claude plugin validate --strict . ``` -Keep a single plugin manifest. Copilot CLI looks for `.plugin/plugin.json`, -then `plugin.json` at the root, then `.github/plugin/plugin.json`, and only -then `.claude-plugin/plugin.json`, so a manifest added in any of those places -(a registry's import tool may write one) would silently take over, and would -be a fourth place to keep the version in. +Keep these two manifests and no others. awesome-copilot reads +`.github/plugin/plugin.json` and `.plugin/plugin.json` before the one at the +root, and Copilot CLI's documented lookup checks `.plugin/plugin.json` first as +well, so a manifest in either place (a registry's import tool may write one) +would silently take over. `check-versions.sh` fails CI unless the two agree +field for field, apart from `$schema`. ### gh skill (GitHub CLI 2.90 or later) @@ -193,8 +198,9 @@ Claiming the listing (`tessl skill import ./skills/envrelay --workspace `, plus a GitHub Action with a Tessl API key as a secret) is optional, and two things argue against doing it casually. Publishing a skill publicly on Tessl cannot be undone. And the import generates a Tessl -`plugin.json`: see where it lands before committing it ("Keep a single plugin -manifest", above). +`plugin.json`, while the root already has one: see where the generated one +lands before committing anything ("Keep these two manifests and no others", +above). ### Directories that crawl GitHub @@ -235,9 +241,11 @@ is MIT-0, while the repository stays MIT OR Apache-2.0. To publish: -1. Install the CLI and sign in. The login is a device code confirmed in the - browser. ClawHub accepts uploads only from GitHub accounts older than a - minimum age; how old was not verified. +1. Install the CLI and sign in. It has to be version 0.23 or later: older + ones have no `--categories`, which publishing needs (`clawhub -V` prints + the version). The login is a device code confirmed in the browser. ClawHub + accepts uploads only from GitHub accounts older than a minimum age; how old + was not verified. ```bash npm i -g clawhub @@ -255,7 +263,8 @@ To publish: ``` 3. Publish from a checkout of the release tag, so that the version on ClawHub - and `metadata.version` agree, and dry-run first. + and `metadata.version` agree, and dry-run first. The `--source-*` options + link the listing to the tag's commit. [`.clawhubignore`](../skills/envrelay/.clawhubignore) leaves out Python bytecode, which ClawHub refuses. `git switch -` goes back to your branch afterwards. @@ -265,13 +274,18 @@ To publish: ``` ```bash - clawhub skill publish ./skills/envrelay --owner futrixdev --dry-run + clawhub skill publish ./skills/envrelay --owner futrixdev --name EnvRelay --version 1.0.0 --changelog "First release." --categories operations,development --topics backup,restore,migration,dotfiles,developer-environment --source-repo FutrixDev/envrelay-skill --source-commit "$(git rev-parse HEAD)" --source-ref v1.0.0 --source-path skills/envrelay --dry-run ``` ```bash - clawhub skill publish ./skills/envrelay --owner futrixdev --version 1.0.0 + clawhub skill publish ./skills/envrelay --owner futrixdev --name EnvRelay --version 1.0.0 --changelog "First release." --categories operations,development --topics backup,restore,migration,dotfiles,developer-environment --source-repo FutrixDev/envrelay-skill --source-commit "$(git rev-parse HEAD)" --source-ref v1.0.0 --source-path skills/envrelay ``` + For a later release, change the tag, `--version` and `--changelog`. The + upload stays hidden while ClawHub reviews it (`clawhub inspect` shows + `pending.publication`). v1.0.0's scan came back clean within a minute; how + long publication takes after that was not verified. + 4. Check the listing: ```bash @@ -284,9 +298,9 @@ To publish: Every upload is scanned (VirusTotal, ClawScan and static analysis). A scanner is most likely to stop at the installer, which downloads a binary: the -frontmatter's `metadata.openclaw` declares what the skill needs and SKILL.md -says what the installer does, and the review compares those with the code. If a -listing is held, read the report: +frontmatter's top-level `clawdis` block declares what the skill needs (ADR-026) +and SKILL.md says what the installer does, and the review compares those with +the code. If a listing is held, read the report: ```bash clawhub scan download envrelay --version 1.0.0 @@ -322,20 +336,30 @@ install with `smithery skill add NAMESPACE/envrelay --agent claude-code`. A listing in [github/awesome-copilot](https://github.com/github/awesome-copilot) puts the plugin in the marketplace that Copilot CLI and VS Code ship with. +Submit v1.0.1 or later: v1.0.0 has no manifest where they look, and its +frontmatter fails their lint (ADR-026). - For a plugin that lives in its own repository, use their external-plugin issue form; their CONTRIBUTING.md links it. Do not open a pull request that copies the skill into their repository: it would be relicensed MIT there. - The form asks for the repository, a release tag with its full 40-character - commit SHA, a semver version, the license, the author and keywords. The SHA: + commit SHA, a semver version, the license, the author and keywords. The + version must be the one in the tag's root `plugin.json`, which is where they + find the manifest. The SHA: ```bash - git rev-list -n 1 v1.0.0 + git rev-list -n 1 v1.0.1 ``` -- They lint the plugin (`vally lint`), test an install with Copilot CLI, and a - maintainer approves it. Listings are reviewed again every six months. How a - listed entry moves to a newer tag was not verified; see their CONTRIBUTING.md. +- Their checks run `vally lint` over the whole repository (the manifest names + no skills directory), install the plugin with Copilot CLI from a marketplace + made on the spot, and check the manifest against the Agent Plugins + specification. Then a maintainer approves it. Listings are reviewed again + every six months. How a listed entry moves to a newer tag was not verified; + see their CONTRIBUTING.md. +- `vally lint` refuses a SKILL.md `metadata` value that is not a string, which + is why ClawHub's declarations sit in a top-level `clawdis` block. Keep them + there. ## 4. Awesome lists @@ -355,7 +379,7 @@ Right after the first release: |---|---|---| | [ComposioHQ/awesome-claude-skills](https://github.com/ComposioHQ/awesome-claude-skills) | Pull request titled `Add EnvRelay skill`, adding one line in alphabetical order: `- [EnvRelay](https://github.com/FutrixDev/envrelay-skill) - One sentence.` | Keep the alphabetical order | | [hesreallyhim/awesome-claude-code](https://github.com/hesreallyhim/awesome-claude-code) | The "recommend a resource" issue form on the web. Pull requests and issues opened with `gh` are closed | Written by a person. Eligible 14 days after the repository's first commit (2026-09-25, so from 2026-10-09) with ongoing activity, or at 100 stars. GitHub must detect the license | -| [github/awesome-copilot](https://github.com/github/awesome-copilot) | The external-plugin form, above | Needs the release tag | +| [github/awesome-copilot](https://github.com/github/awesome-copilot) | The external-plugin form, above | Needs a release tag, v1.0.1 or later | Once people use it: @@ -383,7 +407,7 @@ Not these: ## 5. Later - **Gemini CLI's extension gallery.** It needs a `gemini-extension.json` at the - repository root (a fourth version to keep in step, which `check-versions.sh` + repository root (a fifth version to keep in step, which `check-versions.sh` would have to learn) and the `gemini-cli-extension` topic, and how the gallery treats release assets that do not follow its `{platform}.{arch}.{name}.{ext}` naming was not verified. Gemini CLI already @@ -409,7 +433,7 @@ Not these: ## 7. Every release -1. Bump the version in its three places (README, "Releasing"), check the +1. Bump the version in its four places (README, "Releasing"), check the plugin with `claude plugin validate --strict .`, and merge. 2. **Tag right after the merge.** Until the release is out, a skill installed from the default branch asks for a release that does not exist yet, and its diff --git a/plugin.json b/plugin.json new file mode 100644 index 0000000..75a1b8d --- /dev/null +++ b/plugin.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", + "name": "envrelay", + "version": "1.0.1", + "description": "Move a development environment to a new machine: back up dotfiles, credentials, git repositories, AI coding agent state and installed software into one passphrase-encrypted file, then restore it step by step.", + "author": { + "name": "FutrixDev", + "url": "https://github.com/FutrixDev" + }, + "homepage": "https://envrelay.com/", + "repository": "https://github.com/FutrixDev/envrelay-skill", + "license": "MIT OR Apache-2.0", + "keywords": ["backup", "restore", "migration", "dotfiles", "developer-environment", "new-machine"] +} diff --git a/skills/envrelay/SKILL.md b/skills/envrelay/SKILL.md index 7b94733..618edba 100644 --- a/skills/envrelay/SKILL.md +++ b/skills/envrelay/SKILL.md @@ -4,23 +4,23 @@ description: Use when backing up, restoring, or migrating a development environm compatibility: Needs macOS or Linux with a terminal the user can type into, python3 3.9 or newer, git, and the envrelay binary, which the skill's own installer adds once the user agrees. allowed-tools: Bash(python3 ${CLAUDE_SKILL_DIR}/scripts/*) metadata: - version: "1.0.0" - openclaw: - requires: - bins: - - python3 - - git - envVars: - - name: ENVRELAY_BIN_DIR - required: false - description: Where install.sh puts the envrelay binary instead of ~/.local/bin. - - name: ENVRELAY_DOWNLOAD_URL - required: false - description: A mirror, or a local directory of release assets, that install.sh downloads from instead of GitHub releases. - os: - - darwin - - linux - homepage: https://envrelay.com/ + version: "1.0.1" +clawdis: + requires: + bins: + - python3 + - git + envVars: + - name: ENVRELAY_BIN_DIR + required: false + description: Where install.sh puts the envrelay binary instead of ~/.local/bin. + - name: ENVRELAY_DOWNLOAD_URL + required: false + description: A mirror, or a local directory of release assets, that install.sh downloads from instead of GitHub releases. + os: + - darwin + - linux + homepage: https://envrelay.com/ --- # EnvRelay diff --git a/tests/installer.sh b/tests/installer.sh index 558ed65..4791bf1 100755 --- a/tests/installer.sh +++ b/tests/installer.sh @@ -178,16 +178,16 @@ chmod 644 "$link/install.sh" cat >"$link/SKILL.md" <<'EOF' --- allowed-tools: Bash(python3 ${CLAUDE_SKILL_DIR}/scripts/*) +clawdis: + requires: + bins: + - python3 description: Use when backing up or restoring a development environment. metadata: github-path: skills/envrelay github-ref: v9.8.6 github-repo: https://github.com/FutrixDev/envrelay-skill github-tree-sha: 4b825dc642cb6eb9a060e54bf8d69288fbee4904 - openclaw: - requires: - bins: - - python3 version: 9.8.6 name: envrelay ---