diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 44b5c9c..9db1a0e 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ "name": "github-build-or-reuse", "source": "./", "description": "Search GitHub before you build, vet open-source alternatives, then decide USE, CONTRIBUTE, FORK, or BUILD.", - "version": "1.2.1" + "version": "1.2.2" } ] } diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 3eb0b7b..676b4d9 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-build-or-reuse", - "version": "1.2.1", + "version": "1.2.2", "description": "Search GitHub before you build, vet open-source alternatives, then decide USE, CONTRIBUTE, FORK, or BUILD.", "author": { "name": "GitHub Community Spain", @@ -14,6 +14,7 @@ "open-source", "open-source-alternatives", "agent-skills", + "agent-plugins", "github-copilot", "codex", "claude-code", diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 3eb0b7b..676b4d9 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-build-or-reuse", - "version": "1.2.1", + "version": "1.2.2", "description": "Search GitHub before you build, vet open-source alternatives, then decide USE, CONTRIBUTE, FORK, or BUILD.", "author": { "name": "GitHub Community Spain", @@ -14,6 +14,7 @@ "open-source", "open-source-alternatives", "agent-skills", + "agent-plugins", "github-copilot", "codex", "claude-code", diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index de38095..73a332d 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -26,6 +26,9 @@ jobs: - name: Validate repository packaging run: python scripts/validate.py + - name: Validate Agent Plugin and skills.sh coexistence + run: python scripts/validate-agent-plugin.py + - name: Validate generated cross-agent manifests run: python scripts/generate-distribution.py --check diff --git a/AGENTS.md b/AGENTS.md index 1dbe5f0..a87db7a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,15 +5,26 @@ This repository publishes one portable Agent Skill and platform packaging around ## Source of truth - Canonical runtime skill: `skills/github-build-or-reuse/` -- OpenAI plugin manifest: `.codex-plugin/plugin.json` -- Repo marketplace: `.agents/plugins/marketplace.json` +- Portable Agent Plugins v1 manifest: `plugin.json` +- skills.sh grouping metadata: `skills.sh.json` +- Generated host adapters: `.codex-plugin/`, `.claude-plugin/`, `.cursor-plugin/`, `.agents/plugins/`, `marketplace.json`, `gemini-extension.json` - Project docs: `docs/` - README demo evidence: `assets/demo.json` - Demo generator: `scripts/generate_demo.py` +- Distribution generator: `scripts/generate-distribution.py` - Repository validation: `scripts/validate.py` +- Agent Plugin / skills.sh contract validation: `scripts/validate-agent-plugin.py` Do not recreate a second root `SKILL.md` or duplicate the canonical skill into platform-specific directories. +## Distribution invariants + +- Agent Plugins adoption complements Agent Skills and skills.sh; it does not replace them. +- Preserve repository `ghspain/github-build-or-reuse`, skill name `github-build-or-reuse`, and path `skills/github-build-or-reuse/SKILL.md` unless a deliberate migration is explicitly planned. +- `skills.sh.json` and Agent Plugins fixed discovery from `skills/*/SKILL.md` must expose the same canonical skill set. +- Keep `plugin.json` portable: Agent Plugins v1 fields only. Host-specific metadata belongs in generated adapters/extensions, not invented top-level fields. +- Do not claim runtime compatibility merely because a host manifest can be generated. Classify evidence as manifest-only, install/discovery verified, or runtime verified. + ## Principles - Keep `SKILL.md` concise and imperative; put detailed evidence recipes and edge cases in local references/examples. @@ -33,7 +44,9 @@ Run: ```bash python scripts/validate.py +python scripts/validate-agent-plugin.py +python scripts/generate-distribution.py --check python scripts/generate_demo.py --check ``` -CI additionally validates the canonical directory against the Agent Skills reference validator and checks that generated demo assets match their evidence source. +CI additionally validates the canonical directory against the Agent Skills reference validator, verifies `npx skills` discovery, and checks that generated distribution/demo assets match their canonical sources. diff --git a/CHANGELOG.md b/CHANGELOG.md index f9f6029..e8c7d86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,26 @@ All notable changes to this project will be documented here. ## [Unreleased] +## [1.2.2] - 2026-09-04 + +### Added + +- Agent Plugins 1.0 / skills.sh coexistence validator that requires both distribution surfaces to expose the same canonical `github-build-or-reuse` skill. +- ADR documenting Agent Plugins as a packaging layer over the existing Agent Skill rather than a migration away from Agent Skills or skills.sh. +- Compatibility evidence matrix separating conformance/manifest compatibility, install/discovery verification and runtime verification. +- `agent-plugins` discovery metadata across generated packaging surfaces. + +### Changed + +- CI now validates the portable Agent Plugin contract alongside the existing Agent Skills reference validation and `npx skills` discovery smoke test. +- Repository guidance now treats the repository name, skill identity and `skills/github-build-or-reuse/SKILL.md` path as distribution invariants unless a deliberate migration is planned. +- Standards documentation makes the no-custom-MCP decision explicit until a real capability gap is demonstrated. + +### Compatibility + +- The runtime decision model is unchanged from 1.2.1. +- Existing skills.sh / `npx skills` discovery remains supported with the same repository, skill name, canonical path and `skills.sh.json` registration. + ## [1.2.1] - 2026-09-03 ### Added diff --git a/README.md b/README.md index cc34f3c..e209501 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,13 @@ **Don't reinvent the wheel with AI-generated code. Search GitHub first, vet the best open-source options, then decide whether to USE, CONTRIBUTE, FORK, or BUILD.** -`github-build-or-reuse` is a portable **Agent Skill for GitHub Copilot, Codex, Claude Code, Cursor and other Agent Skills-compatible coding agents**. It turns “has somebody already built this?” into a repeatable engineering gate before substantial implementation. +`github-build-or-reuse` is a portable **Agent Skill and Agent Plugins 1.0 package for GitHub Copilot, Codex, Claude Code, Cursor and other compatible coding agents**. It turns “has somebody already built this?” into a repeatable engineering gate before substantial implementation. [![Validate](https://github.com/ghspain/github-build-or-reuse/actions/workflows/validate.yml/badge.svg)](https://github.com/ghspain/github-build-or-reuse/actions/workflows/validate.yml) [![Release](https://img.shields.io/github/v/release/ghspain/github-build-or-reuse)](https://github.com/ghspain/github-build-or-reuse/releases) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Agent Skill](https://img.shields.io/badge/Agent%20Skill-portable-1f6feb)](skills/github-build-or-reuse/SKILL.md) +[![Agent Plugins 1.0](https://img.shields.io/badge/Agent%20Plugins-1.0-8250df)](plugin.json) [![skills.sh](https://skills.sh/b/ghspain/github-build-or-reuse)](https://skills.sh/ghspain/github-build-or-reuse/github-build-or-reuse) ## In 20 seconds @@ -41,7 +42,9 @@ The `Render README demo` workflow reuses the official [`asciinema/agg`](https:// ## Install -### `npx skills` — easiest cross-agent path +### `npx skills` / skills.sh — easiest cross-agent path + +This remains a first-class supported installation path. Agent Plugins adoption does **not** replace or relocate the canonical skill used by skills.sh. ```bash # Inspect before installing @@ -54,6 +57,21 @@ npx skills@latest add ghspain/github-build-or-reuse --skill github-build-or-reus npx skills@latest add ghspain/github-build-or-reuse --skill github-build-or-reuse --agent codex --global ``` +### Agent Plugins 1.0 + +The repository root is also a portable Agent Plugins 1.0 package: + +```text +plugin.json +skills/ +└── github-build-or-reuse/ + └── SKILL.md +``` + +Agent Plugins discovers the **same** canonical skill from the fixed `skills/` directory that skills.sh uses. CI verifies that Agent Plugins discovery and `skills.sh.json` expose the same skill, so adding plugin packaging cannot silently drop the existing skills.sh path. + +Use the Agent Plugin installation mechanism supported by your client. Host-specific compatibility surfaces below are generated from the same canonical distribution state; they are not copies of the skill. + ### GitHub CLI / GitHub Copilot GitHub CLI **2.90.0+** can preview, install and update Agent Skills directly from GitHub repositories: @@ -63,7 +81,7 @@ gh skill preview ghspain/github-build-or-reuse github-build-or-reuse gh skill install ghspain/github-build-or-reuse github-build-or-reuse # Reproducible release -gh skill install ghspain/github-build-or-reuse github-build-or-reuse@v1.2.0 +gh skill install ghspain/github-build-or-reuse github-build-or-reuse@v1.2.2 ``` For long-lived environments, prefer a release tag or `--pin` so upstream changes cannot silently alter behavior. @@ -71,7 +89,7 @@ For long-lived environments, prefer a release tag or `--pin` so upstream changes ### ChatGPT / Codex plugin ```bash -codex plugin marketplace add ghspain/github-build-or-reuse --ref v1.2.0 +codex plugin marketplace add ghspain/github-build-or-reuse --ref v1.2.2 ``` Then open `/plugins`, choose the **GitHub Community Spain** marketplace and install **GitHub Build or Reuse**. @@ -89,6 +107,8 @@ Copy or install that directory into the skills location supported by your client +See [`docs/agent-plugin-compatibility.md`](docs/agent-plugin-compatibility.md) for the distribution invariants and evidence-based compatibility matrix. + ## Why search before you build? AI coding agents made greenfield software dramatically cheaper to *start*. They did not make it free to own. @@ -203,22 +223,26 @@ The project follows its own rule: **reuse before build**. The workflow already works with host-provided GitHub connectors/API, existing MCP integrations, authenticated `gh`, or web research. A bespoke GitHub-wrapper MCP would add authentication, maintenance and security surface without a unique capability. +Agent Plugins 1.0 supports optional MCP packaging, but format support alone is not a reason to add a server. + ### Tool degradation must be visible The skill prefers structured GitHub evidence, but it does not pretend unavailable checks succeeded. Missing evidence is reported explicitly; candidate repository content is treated as untrusted input. ## Standards and compatibility -The canonical skill follows the open **Agent Skills** specification. The repository also follows OpenAI plugin packaging conventions (`.codex-plugin/plugin.json` + `skills/`). `AGENTS.md` remains maintainer guidance rather than runtime skill content. +The canonical skill follows the open **Agent Skills** specification. The repository root also follows **Agent Plugins 1.0** (`plugin.json` + `skills/`) while preserving `skills.sh.json` and the existing skills.sh discovery path. Host-specific Codex, Claude Code, Cursor and Gemini manifests remain generated compatibility adapters. `AGENTS.md` remains maintainer guidance rather than runtime skill content. -See [`docs/standards-and-roadmap.md`](docs/standards-and-roadmap.md) for the design rationale around Agent Skills, plugins, AGENTS.md, OpenAI Agents SDK definitions and MCP. +See [`docs/standards-and-roadmap.md`](docs/standards-and-roadmap.md) and [`docs/agent-plugin-compatibility.md`](docs/agent-plugin-compatibility.md) for the design rationale, compatibility evidence and MCP decision. ## Quality and evals -The skill ships with output evals and trigger queries under [`skills/github-build-or-reuse/evals/`](skills/github-build-or-reuse/evals/). CI validates repository packaging, generated demo consistency, the Agent Skills reference specification, GitHub CLI publishing when available, and discovery by `npx skills`. +The skill ships with output evals and trigger queries under [`skills/github-build-or-reuse/evals/`](skills/github-build-or-reuse/evals/). CI validates repository packaging, Agent Plugins/skills.sh coexistence, generated demo consistency, the Agent Skills reference specification, GitHub CLI publishing when available, and discovery by `npx skills`. ```bash python scripts/validate.py +python scripts/validate-agent-plugin.py +python scripts/generate-distribution.py --check python scripts/generate_demo.py --check ``` @@ -232,16 +256,20 @@ python scripts/generate_demo.py --check │ ├── demo.svg # deterministic static rendering │ ├── demo.cast # deterministic asciinema recording │ └── demo.gif # generated by the render workflow +├── plugin.json # portable Agent Plugins 1.0 manifest +├── skills.sh.json # skills.sh grouping/discovery metadata ├── .agents/plugins/marketplace.json ├── .codex-plugin/plugin.json ├── .github/workflows/ │ ├── render-demo.yml │ └── validate.yml ├── docs/ +│ ├── agent-plugin-compatibility.md │ └── demo.md ├── scripts/ │ ├── generate_demo.py -│ └── validate.py +│ ├── generate-distribution.py +│ └── validate-agent-plugin.py ├── skills/github-build-or-reuse/ ├── AGENTS.md ├── CHANGELOG.md @@ -261,7 +289,7 @@ The implementations are independent. Related projects are useful precisely becau ## Search keywords -Agent Skills · GitHub Copilot skill · Codex skill · Claude Code skill · open-source alternatives · GitHub repository search · software reuse · build vs buy · build vs open source · don't reinvent the wheel · repository due diligence · open-source due diligence · GitHub automation · AI coding agents · software architecture · reuse before build. +Agent Plugins · Agent Skills · GitHub Copilot skill · Codex skill · Claude Code skill · open-source alternatives · GitHub repository search · software reuse · build vs buy · build vs open source · don't reinvent the wheel · repository due diligence · open-source due diligence · GitHub automation · AI coding agents · software architecture · reuse before build. ## Contributing diff --git a/distribution.config.json b/distribution.config.json index 3bba9c1..41c8082 100644 --- a/distribution.config.json +++ b/distribution.config.json @@ -18,6 +18,7 @@ "open-source", "open-source-alternatives", "agent-skills", + "agent-plugins", "github-copilot", "codex", "claude-code", diff --git a/docs/adr/0001-agent-plugin-and-skills-sh-coexistence.md b/docs/adr/0001-agent-plugin-and-skills-sh-coexistence.md new file mode 100644 index 0000000..986a00a --- /dev/null +++ b/docs/adr/0001-agent-plugin-and-skills-sh-coexistence.md @@ -0,0 +1,51 @@ +# ADR 0001: Agent Plugins complements Agent Skills and skills.sh + +- Status: Accepted +- Date: 2026-09-04 +- Issue: https://github.com/ghspain/github-build-or-reuse/issues/28 +- Parent initiative: https://github.com/svg153/skills/issues/33 + +## Context + +The repository already publishes a portable Agent Skill and several generated host-specific packaging surfaces. Agent Plugins 1.0 standardizes a portable plugin root with fixed discovery of Agent Skills from `skills/` and optional MCP servers from `mcp.json`. + +The project is also already discoverable through the Agent Skills / skills.sh ecosystem. Replacing that layout with a plugin-specific copy would risk breaking existing installation paths and create two runtime sources of truth. + +## Decision + +1. `skills/github-build-or-reuse/SKILL.md` remains the only canonical runtime skill. +2. The repository root is also a conforming Agent Plugins 1.0 package through `plugin.json` plus the existing fixed `skills/` directory. +3. `skills.sh.json` remains a supported distribution surface. Agent Plugin adoption must not rename, move, or duplicate the canonical skill as an incidental packaging change. +4. CI enforces parity between the skills Agent Plugins discovers from `skills/*/SKILL.md` and the skills registered in `skills.sh.json`. +5. Host-specific manifests remain generated adapters and cannot override the portable runtime source. +6. No custom GitHub-wrapper MCP is bundled unless a future evidence-backed capability gap requires one. Existing native connectors, GitHub MCP integrations, `gh`, GitHub APIs, and web research are preferred. +7. Compatibility documentation must distinguish schema/manifest compatibility, install/discovery verification, and actual runtime verification. + +## Consequences + +### Positive + +- Existing skills.sh and Agent Skills users retain the same repository, skill name, and canonical path. +- Agent Plugins-compatible clients can consume the repository without a second copy of the skill. +- Distribution drift becomes testable rather than a documentation convention. +- Future host adapters can be removed as clients converge on Agent Plugins without rewriting runtime behavior. + +### Trade-offs + +- External skills.sh indexing availability cannot be guaranteed by repository CI; only the stable repository inputs and local discovery path can be guaranteed. +- Some client-specific adapters remain necessary until those clients consume the portable package directly. +- Runtime compatibility still has to be tested per client; a valid manifest alone is not proof of equivalent execution. + +## Rejected alternatives + +### Move the skill into a plugin-only directory + +Rejected because Agent Plugins already discovers the existing `skills/` layout and moving it would risk breaking skills.sh and Agent Skills consumers for no capability gain. + +### Duplicate `SKILL.md` for every platform + +Rejected because copies drift and make provenance, releases, fixes, and behavioral eval ownership ambiguous. + +### Bundle a custom GitHub MCP immediately + +Rejected because the project already has multiple ways to collect GitHub evidence and a wrapper would contradict the reuse-before-build principle without a demonstrated missing capability. diff --git a/docs/agent-plugin-compatibility.md b/docs/agent-plugin-compatibility.md new file mode 100644 index 0000000..77cd38c --- /dev/null +++ b/docs/agent-plugin-compatibility.md @@ -0,0 +1,110 @@ +# Agent Plugin compatibility and distribution contract + +`github-build-or-reuse` uses **one canonical Agent Skill** and exposes it through multiple distribution surfaces. Agent Plugins 1.0 is the preferred future package boundary; it does not create a second runtime implementation. + +## Canonical runtime source + +The only runtime skill source is: + +```text +skills/github-build-or-reuse/SKILL.md +``` + +Both Agent Plugins v1 and skills.sh must continue discovering that exact directory during the current compatibility phase. A root `SKILL.md` or a platform-specific copy would create competing sources of truth and is rejected by repository validation. + +An Agent Plugin may become the primary installable capability without replacing this file: Agent Skills are a standard component type inside Agent Plugins. + +## Stability contract for skills.sh + +The following identifiers are release invariants unless a deliberate migration is planned: + +- repository: `ghspain/github-build-or-reuse`; +- skill name: `github-build-or-reuse`; +- canonical path: `skills/github-build-or-reuse/SKILL.md`; +- skills.sh registration: `skills.sh.json` includes `github-build-or-reuse`; +- Agent Plugins discovery: the same skill is an immediate child of `skills/`. + +`scripts/validate-agent-plugin.py` compares the Agent Plugins-discovered skill set with the skills registered in `skills.sh.json`. CI also executes `npx skills@latest add . --list` and requires `github-build-or-reuse` to be discovered. A packaging change that moves or renames the canonical skill without updating both contracts therefore fails before merge. + +External skills.sh search/index ranking is not controlled by this repository, so it is not used as a blocking CI dependency. The repository instead preserves every stable input used by skills.sh discovery and validates the local CLI discovery path on every pull request. + +skills.sh is treated as a **discovery/install adapter**, not as another runtime source. Its eventual retirement requires equivalent practical discovery/install reach, not merely the existence of `plugin.json`. That decision is tracked in `svg153/skills#34`. + +## Agent Plugins 1.0 package + +The portable package is rooted at the repository root: + +```text +plugin.json +skills/ + github-build-or-reuse/ + SKILL.md +``` + +Agent Plugins 1.0 discovers skills from the fixed `skills/` location. `plugin.json` therefore contains only portable manifest metadata and does not duplicate a `skills` path field. + +### Optional MCP composition + +Agent Plugins can also discover a root `mcp.json`. That file is a **connection/launch contract**, not proof that the plugin repository implements the MCP server itself. + +A conforming plugin may reuse: + +- an existing remote MCP server via `streamable-http`; +- an existing executable via `stdio`; +- legacy `sse` where compatibility requires it. + +Agent Plugins 1.0 does not define package-manager resolution of MCP dependencies by package name. It also does not define portable OAuth credential references. Authentication is client-managed, and plugin source must not embed secrets in HTTP headers. + +The general reusable MCP composition model is tracked in `svg153/skills#35`; the planning multi-MCP pilot is `svg153/skills#36`. + +### Why this package currently has no `mcp.json` + +`github-build-or-reuse` can collect GitHub evidence through host-native GitHub access, the official/existing GitHub MCP Server, authenticated `gh`, the GitHub API, or web research. Making one of these paths mandatory would reduce portability without adding a unique capability. + +Therefore the absence of `mcp.json` here means **no mandatory MCP dependency for this capability**, not “Agent Plugins should not reuse external MCPs”. A bespoke GitHub-wrapper MCP remains unjustified unless a differentiating capability gap appears. + +## Compatibility evidence matrix + +Compatibility claims are deliberately separated by evidence strength. + +| Surface | Current evidence | Classification | +| --- | --- | --- | +| Agent Plugins 1.0 root package | fixed-layout + closed-field validation in CI | conformance/discovery verified | +| Agent Skills reference format | upstream `skills-ref validate` in CI | format verified | +| skills.sh / `npx skills` | `npx skills@latest add . --list` in CI | local install/discovery verified | +| GitHub CLI `gh skill` | `gh skill publish --dry-run` when runner CLI supports it | publish-path verified when available | +| Codex adapter | generated from canonical distribution config | manifest compatibility; runtime verification pending | +| Claude Code adapter | generated from canonical distribution config | manifest compatibility; runtime verification pending | +| Cursor adapter | generated from canonical distribution config | manifest compatibility; runtime verification pending | +| Gemini CLI adapter | generated from canonical distribution config | manifest compatibility; runtime verification pending | +| GitHub Agentic Workflows | no runtime evidence captured yet | pending | + +Do not rewrite a **manifest compatibility** result as "runs everywhere". Runtime claims should include client/version/date and the command or evidence used to verify them. + +## Host-specific adapters + +`.codex-plugin/`, `.claude-plugin/`, `.cursor-plugin/`, `.agents/plugins/`, `marketplace.json`, and `gemini-extension.json` are compatibility/distribution outputs generated from canonical state. They must not become independent runtime copies. + +The intended migration is to retire these surfaces **individually** when the corresponding client has Agent Plugin-native parity for installation, discovery, updates and runtime. Do not delete them as a batch merely because the portable manifest exists. + +Regenerate and check them with: + +```bash +python scripts/generate-distribution.py +python scripts/generate-distribution.py --check +``` + +## Security baseline + +A distributable change must preserve these properties: + +- no secrets or credentials in plugin metadata or `mcp.json`; +- portable `plugin.json` only uses Agent Plugins v1 fields; +- any `mcp.json` matches the same Agent Plugins specification version; +- remote MCP endpoints use a reviewed HTTPS origin and no embedded credential header; +- referenced skill content stays inside the repository package; +- external Actions remain full-SHA pinned with explicit permissions and timeouts; +- no custom MCP implementation is added without a concrete capability requirement; +- existing third-party MCP composition is allowed when it is part of the capability contract and has provenance/security review; +- license/provenance information remains intact; +- runtime compatibility is stated at the evidence level actually verified. diff --git a/docs/releases/v1.2.2.md b/docs/releases/v1.2.2.md new file mode 100644 index 0000000..b542024 --- /dev/null +++ b/docs/releases/v1.2.2.md @@ -0,0 +1,43 @@ +# v1.2.2 — Agent Plugins 1.0 compatibility without breaking skills.sh + +This patch release makes Agent Plugins 1.0 a first-class distribution contract while preserving the existing Agent Skills and skills.sh installation paths. + +## What changed + +- Added an explicit architecture decision that `skills/github-build-or-reuse/SKILL.md` remains the single canonical runtime source for Agent Plugins, Agent Skills and skills.sh consumers. +- Added `scripts/validate-agent-plugin.py` to verify the portable `plugin.json`, fixed `skills/` discovery, version alignment, generated adapters, and exact parity with skills registered in `skills.sh.json`. +- CI now runs the Agent Plugin / skills.sh coexistence validator in addition to the existing Agent Skills reference validation and `npx skills@latest add . --list` discovery smoke test. +- Added a compatibility evidence matrix that distinguishes conformance/manifest compatibility, install/discovery verification, and actual runtime verification. +- Documented the deliberate decision not to bundle a bespoke GitHub MCP server without a demonstrated capability gap. +- Added `agent-plugins` to distribution discovery metadata and regenerated affected manifests. + +## skills.sh compatibility + +This release deliberately keeps all stable skills.sh inputs unchanged: + +- repository: `ghspain/github-build-or-reuse`; +- skill: `github-build-or-reuse`; +- path: `skills/github-build-or-reuse/SKILL.md`; +- registration: `skills.sh.json` still includes `github-build-or-reuse`. + +The new validator fails if the Agent Plugins-discovered skill set diverges from the skills.sh registration, providing a regression guard against future packaging changes accidentally dropping the skill from the existing ecosystem. + +External skills.sh indexing/ranking remains outside repository control, so it is not made a brittle blocking CI dependency. The repository instead preserves and tests the stable discovery inputs under its control. + +## Runtime behavior + +There is **no change** to the USE / CONTRIBUTE / FORK / BUILD decision model or to the skill's activation and evidence rules. This is a packaging, governance and compatibility hardening release. + +## Install + +Existing installation remains valid: + +```bash +npx skills@latest add ghspain/github-build-or-reuse --skill github-build-or-reuse +``` + +Or with supporting GitHub CLI versions: + +```bash +gh skill install ghspain/github-build-or-reuse github-build-or-reuse@v1.2.2 +``` diff --git a/docs/standards-and-roadmap.md b/docs/standards-and-roadmap.md index 4a6086e..15e4ab4 100644 --- a/docs/standards-and-roadmap.md +++ b/docs/standards-and-roadmap.md @@ -1,10 +1,49 @@ # Standards, packaging and roadmap -This project deliberately separates **portable behavior** from **platform packaging**. +This project deliberately separates **portable behavior** from **capability packaging and distribution**. ## Portable core: Agent Skills -The canonical skill lives at `skills/github-build-or-reuse/`. It follows the open Agent Skills specification: a directory named after the skill, a `SKILL.md` with YAML frontmatter, and optional references, examples, scripts and evals. This is the source that Agent Skills-compatible clients should consume. +The canonical skill lives at `skills/github-build-or-reuse/`. It follows the open Agent Skills specification: a directory named after the skill, a `SKILL.md` with YAML frontmatter, and optional references, examples, scripts and evals. This remains the source of portable runtime behavior even if Agent Plugins becomes the preferred package boundary. + +The canonical path and skill identity are also compatibility invariants for skills.sh. Agent Plugins adoption must not move, rename or duplicate this runtime source as an incidental packaging change. + +## Portable package: Agent Plugins 1.0 + +The repository root is also a portable Agent Plugins 1.0 package: + +```text +plugin.json +skills/ + github-build-or-reuse/ + SKILL.md +``` + +Agent Plugins v1 discovers Agent Skills from the fixed `skills/` directory, so the existing Agent Skills / skills.sh layout is reused directly. `plugin.json` contains portable metadata only and does not duplicate a `skills` path field. + +The intended direction is **plugin-first packaging with compatibility adapters**, not a second runtime implementation. An Agent Plugin may become the primary installable capability while `SKILL.md` remains its canonical behavior component. + +During this pilot, `scripts/validate-agent-plugin.py` requires the skill set discovered by Agent Plugins to match the skill set registered in `skills.sh.json`. CI separately runs `npx skills@latest add . --list` and requires `github-build-or-reuse` to remain discoverable. + +See [Agent Plugin compatibility and distribution contract](agent-plugin-compatibility.md) and [ADR 0001](adr/0001-agent-plugin-and-skills-sh-coexistence.md). + +## Can Agent Plugins replace the other surfaces? + +Potentially **some of them, over time**. + +Agent Plugins is a package format for skills and MCP servers. It can remove the need for host-specific packaging adapters once a host consumes the standard natively with equivalent install, discovery, update and runtime behavior. + +It does not make the Agent Skill disappear: the skill is a standard component inside the plugin. It also does not standardize public marketplaces or catalog ranking, so a discovery surface such as skills.sh still has independent value today. + +Retirement policy therefore follows evidence, not file-count reduction: + +1. Prefer Agent Plugins as the package boundary. +2. Keep `SKILL.md` as canonical behavior. +3. Retire host-specific generated adapters individually after native Agent Plugin parity is verified. +4. Keep skills.sh while it materially adds discovery/install reach. +5. Reassess skills.sh only after an equivalent Agent Plugin-native discovery path exists or skills.sh itself consumes Agent Plugins natively. + +The detailed retirement criteria are tracked in `svg153/skills#34`. ## Derived cross-agent packaging @@ -17,9 +56,23 @@ python scripts/generate-distribution.py --check The generated surfaces cover Agent Plugins, Codex, Claude Code, Cursor and Gemini. The richer standalone product metadata (branding, prompts, license, keywords and interface copy) stays in `distribution.config.json` so host manifests remain consistent without flattening the product to the catalog's generic defaults. +A generated adapter is evidence of **manifest compatibility**, not automatically runtime compatibility. Runtime claims must be backed by a client/version/date and install or execution evidence. + ## GitHub Copilot -GitHub Copilot supports the Agent Skills standard across the cloud agent, code review, Copilot CLI, the Copilot app and agent mode in supported IDEs. GitHub CLI also provides `gh skill` commands in supporting versions. The canonical skill remains directly installable; no Copilot-specific copy is maintained. +GitHub Copilot supports the Agent Skills standard across the cloud agent, code review, Copilot CLI, the Copilot app and agent mode in supported IDEs. GitHub CLI also provides `gh skill` commands in supporting versions. The canonical skill remains directly installable; no Copilot-specific runtime copy is maintained. + +## skills.sh + +`skills.sh.json` remains a supported public discovery surface. The repository protects the stable inputs under its control: + +- repository identity `ghspain/github-build-or-reuse`; +- canonical skill name `github-build-or-reuse`; +- canonical path `skills/github-build-or-reuse/SKILL.md`; +- grouping registration in `skills.sh.json`; +- successful local `npx skills` discovery in CI. + +External catalog indexing/ranking is not repository-controlled and is therefore not a blocking CI dependency. We protect the inputs rather than couple every PR to an external search index. ## AGENTS.md @@ -27,7 +80,7 @@ GitHub Copilot supports the Agent Skills standard across the cloud agent, code r ## Release and validation automation -Tagged releases are already automated by `.github/workflows/release.yml`; README demo assets are reproducibly regenerated by `render-demo.yml`; validation checks packaging, Agent Skills conformance, generated-manifest drift and client discovery. +Tagged releases are already automated by `.github/workflows/release.yml`; README demo assets are reproducibly regenerated by `render-demo.yml`; validation checks packaging, the Agent Plugin / skills.sh coexistence contract, Agent Skills conformance, generated-manifest drift and client discovery. All repository workflows follow an enforced security baseline: external Actions are full-SHA pinned, checkout credentials do not persist, permissions are explicit, jobs have timeouts, and Dependabot tracks GitHub Actions updates. @@ -35,7 +88,7 @@ All repository workflows follow an enforced security baseline: external Actions ### skills.sh Finder -The canonical skills.sh detail page and legacy Finder entry are external distribution surfaces, not repository-owned indexes. Once the owner-scoped Finder returns `ghspain/github-build-or-reuse` with skill `github-build-or-reuse`, this repository treats catalog indexing as complete. +The canonical skills.sh detail page and Finder entry are external distribution surfaces, not repository-owned indexes. Once the owner-scoped Finder returns `ghspain/github-build-or-reuse` with skill `github-build-or-reuse`, this repository treats catalog indexing as complete. Exact-name discoverability and capability/semantic discoverability are separate concerns. The current legacy `skills find` client calls `skills.sh/api/search`; upstream behavior is known to match skill identity/source much more reliably than `SKILL.md` description text. Consequently, adding keyword stuffing to this repository is not considered a valid workaround for semantic search gaps. Capability search improvements belong upstream; see `vercel-labs/skills#1761`. @@ -45,28 +98,49 @@ Temporary discovery probes should be removed after owner-scoped indexing and exa ## MCP decision -### Current verdict: do not bundle a custom MCP server +### Agent Plugins MCP composition is broader than custom MCP implementation + +Agent Plugins v1 optionally discovers MCP configuration from root `mcp.json`. That configuration may describe: -The workflow needs GitHub discovery and repository evidence, not a novel protocol or proprietary data source. Prefer, in order: +- an existing remote MCP server using `streamable-http`; +- an existing executable using `stdio`; +- legacy `sse` where compatibility requires it. + +The MCP server therefore does **not** need to be implemented by the plugin repository. A capability can package its skills and declare existing third-party tool servers as part of the same installable contract. + +Agent Plugins v1 does not define a package-manager dependency mechanism such as “install MCP package X by name”. It defines how a client connects to or launches each declared server. Authentication and credential storage are client-managed; credentials must not be committed in `mcp.json` headers. + +Reusable MCP composition is tracked at catalog level in `svg153/skills#35`, with a multi-MCP planning pilot in `svg153/skills#36`. + +### Current verdict for GitHub Build or Reuse: no mandatory `mcp.json` + +The workflow needs GitHub discovery and repository evidence, but it deliberately supports several equivalent access paths. Prefer, in order according to the host: 1. the host's native GitHub connector/API; -2. an existing GitHub MCP integration when supported; +2. the official/existing GitHub MCP integration when supported; 3. authenticated `gh` or GitHub API; 4. web research as fallback/context. A bespoke GitHub wrapper would contradict the project's own reuse principle unless it creates a real capability unavailable through existing integrations. -### Reconsider MCP when +Making the official GitHub MCP a mandatory `mcp.json` dependency would also narrow a skill that currently works through multiple host-native GitHub paths. Therefore this capability keeps `mcp.json` absent unless testing shows that a stable mandatory MCP contract improves behavior enough to justify the coupling. + +This is a **capability-specific decision**, not a recommendation against MCP composition in Agent Plugins generally. + +### Reconsider `mcp.json` here when - a stable cross-host GitHub tool contract is unavailable elsewhere; +- runtime parity depends on one consistent GitHub tool surface; - server-side aggregation/scoring becomes necessary; - organization/private workflows require centralized auth or policy; -- existing MCP implementations cannot satisfy the requirement. +- an existing MCP supplies a required capability that host-native access cannot reliably provide. ## Future iterations 1. Promote behavioral evals to the repository's primary runtime quality gate and measure trigger/boundary behavior under a pinned executor. -2. Test public marketplace/install paths in Codex, Claude Code, Cursor and Gemini rather than assuming manifest compatibility equals runtime parity. -3. Add more worked decision cases (developer portals, feature flags, RAG stacks, self-hosted apps, internal tools). -4. Consider structured machine-readable decision output for CI/agent orchestration. -5. Reconsider MCP only after a concrete tool gap is demonstrated. +2. Capture real install/runtime evidence for Codex, GitHub Copilot, GitHub Agentic Workflows, Claude Code, Cursor and Gemini and maintain the evidence classification in `docs/agent-plugin-compatibility.md`. +3. Feed this pilot into `svg153/skills#34` to decide which host-specific adapters can be retired safely. +4. Generalize optional third-party MCP composition through `svg153/skills#35`. +5. Prove skills + multiple reused MCP servers together with the planning pilot in `svg153/skills#36`. +6. Add more worked decision cases (developer portals, feature flags, RAG stacks, self-hosted apps, internal tools). +7. Consider structured machine-readable decision output for CI/agent orchestration. diff --git a/gemini-extension.json b/gemini-extension.json index e4d0973..b315eb3 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,5 +1,5 @@ { "name": "github-build-or-reuse", - "version": "1.2.1", + "version": "1.2.2", "description": "Search GitHub before you build, vet open-source alternatives, then decide USE, CONTRIBUTE, FORK, or BUILD." } diff --git a/marketplace.json b/marketplace.json index 923a25d..e269673 100644 --- a/marketplace.json +++ b/marketplace.json @@ -12,7 +12,7 @@ "name": "github-build-or-reuse", "source": "./", "description": "Search GitHub before you build, vet open-source alternatives, then decide USE, CONTRIBUTE, FORK, or BUILD.", - "version": "1.2.1" + "version": "1.2.2" } ] } diff --git a/metadata.yaml b/metadata.yaml index bc41f29..38d6a10 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -4,7 +4,7 @@ origin_path: skills/github-build-or-reuse plugin_manifest: .codex-plugin/plugin.json category: github status: active -version: 1.2.1 +version: 1.2.2 sync: enabled: false interval: weekly @@ -13,6 +13,7 @@ tags: - github - open-source - agent-skills + - agent-plugins - github-copilot - codex - claude-code diff --git a/plugin.json b/plugin.json index 65b4c4c..df1a048 100644 --- a/plugin.json +++ b/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "github-build-or-reuse", - "version": "1.2.1", + "version": "1.2.2", "description": "Search GitHub before you build, vet open-source alternatives, then decide USE, CONTRIBUTE, FORK, or BUILD.", "author": { "name": "GitHub Community Spain", @@ -15,6 +15,7 @@ "open-source", "open-source-alternatives", "agent-skills", + "agent-plugins", "github-copilot", "codex", "claude-code", diff --git a/scripts/validate-agent-plugin.py b/scripts/validate-agent-plugin.py new file mode 100644 index 0000000..af24734 --- /dev/null +++ b/scripts/validate-agent-plugin.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +"""Validate the portable Agent Plugin without regressing skills.sh discovery.""" + +from __future__ import annotations + +import json +import re +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +EXPECTED_SKILL = "github-build-or-reuse" +PLUGIN_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" +SKILLS_SH_SCHEMA = "https://skills.sh/schemas/skills.sh.schema.json" +PORTABLE_FIELDS = { + "$schema", + "name", + "version", + "description", + "author", + "homepage", + "repository", + "license", + "keywords", + "extensions", +} +NAME_RE = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$") +SEMVER_RE = re.compile(r"^\d+\.\d+\.\d+$") + + +def fail(message: str) -> "NoReturn": + print(f"ERROR: {message}", file=sys.stderr) + raise SystemExit(1) + + +def load_json(path: Path) -> dict: + try: + data = json.loads(path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError) as exc: + fail(f"{path.relative_to(ROOT)}: invalid JSON: {exc}") + if not isinstance(data, dict): + fail(f"{path.relative_to(ROOT)}: expected an object") + return data + + +def plugin_skills() -> set[str]: + skills_dir = ROOT / "skills" + if not skills_dir.is_dir(): + fail("Agent Plugins fixed skills/ directory is missing") + discovered = { + child.name + for child in skills_dir.iterdir() + if child.is_dir() and (child / "SKILL.md").is_file() + } + if not discovered: + fail("Agent Plugin discovers no skills from skills/*/SKILL.md") + return discovered + + +def skills_sh_skills(config: dict) -> list[str]: + if config.get("$schema") != SKILLS_SH_SCHEMA: + fail("skills.sh.json must preserve the canonical skills.sh schema") + groupings = config.get("groupings") + if not isinstance(groupings, list): + fail("skills.sh.json groupings must be a list") + skills: list[str] = [] + for grouping in groupings: + if not isinstance(grouping, dict) or not isinstance(grouping.get("skills"), list): + fail("each skills.sh grouping must contain a skills list") + for skill in grouping["skills"]: + if not isinstance(skill, str): + fail("skills.sh skill names must be strings") + skills.append(skill) + if len(skills) != len(set(skills)): + fail("skills.sh.json contains duplicate skill registrations") + return skills + + +def validate_manifest(plugin: dict) -> str: + unknown = sorted(set(plugin) - PORTABLE_FIELDS) + if unknown: + fail("plugin.json has non-portable top-level fields: " + ", ".join(unknown)) + if plugin.get("$schema") != PLUGIN_SCHEMA: + fail("plugin.json must target Agent Plugins 1.0.0") + name = plugin.get("name") + if not isinstance(name, str) or not NAME_RE.fullmatch(name): + fail("plugin.json name is invalid") + version = plugin.get("version") + if not isinstance(version, str) or not SEMVER_RE.fullmatch(version): + fail("plugin.json version must be semantic X.Y.Z") + for field in ("description", "homepage", "repository", "license"): + if not isinstance(plugin.get(field), str) or not plugin[field].strip(): + fail(f"plugin.json {field} must be a non-empty string") + author = plugin.get("author") + if not isinstance(author, dict) or not isinstance(author.get("name"), str) or not author["name"].strip(): + fail("plugin.json author.name is required") + keywords = plugin.get("keywords") + if not isinstance(keywords, list) or not keywords or not all(isinstance(item, str) and item for item in keywords): + fail("plugin.json keywords must be a non-empty string list") + if "skills" in plugin: + fail("Agent Plugins v1 discovers skills from fixed skills/; plugin.json must not declare a skills field") + extensions = plugin.get("extensions") + if extensions is not None and not isinstance(extensions, dict): + fail("plugin.json extensions must be an object when present") + return version + + +def main() -> None: + if (ROOT / "SKILL.md").exists(): + fail("root SKILL.md would create a second source of truth") + + plugin = load_json(ROOT / "plugin.json") + version = validate_manifest(plugin) + if plugin.get("name") != EXPECTED_SKILL: + fail(f"portable plugin name must remain {EXPECTED_SKILL}") + + discovered = plugin_skills() + if discovered != {EXPECTED_SKILL}: + fail(f"portable plugin skill set changed unexpectedly: {sorted(discovered)}") + + skills_sh = load_json(ROOT / "skills.sh.json") + indexed = set(skills_sh_skills(skills_sh)) + if indexed != discovered: + fail( + "skills.sh and Agent Plugins must expose the same canonical skill set; " + f"skills.sh={sorted(indexed)} plugin={sorted(discovered)}" + ) + + metadata = (ROOT / "metadata.yaml").read_text(encoding="utf-8") + metadata_match = re.search(r'^version:\s*["\']?(\d+\.\d+\.\d+)["\']?\s*$', metadata, re.MULTILINE) + if not metadata_match or metadata_match.group(1) != version: + fail("plugin.json version must match metadata.yaml") + + skill_text = (ROOT / "skills" / EXPECTED_SKILL / "SKILL.md").read_text(encoding="utf-8") + skill_match = re.search(r'^\s{2}version:\s*["\'](\d+\.\d+\.\d+)["\']\s*$', skill_text, re.MULTILINE) + if not skill_match or skill_match.group(1) != version: + fail("plugin.json version must match canonical SKILL.md metadata.version") + + for adapter in (ROOT / ".codex-plugin/plugin.json", ROOT / ".claude-plugin/plugin.json"): + data = load_json(adapter) + if data.get("skills") != "./skills/": + fail(f"{adapter.relative_to(ROOT)} must continue referencing ./skills/") + if data.get("name") != EXPECTED_SKILL or data.get("version") != version: + fail(f"{adapter.relative_to(ROOT)} identity/version drifted from portable package") + + print( + "OK: Agent Plugins v1 and skills.sh expose the same canonical " + f"{EXPECTED_SKILL} skill at version {version}" + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/validate.py b/scripts/validate.py index 0f5456d..e26a383 100755 --- a/scripts/validate.py +++ b/scripts/validate.py @@ -41,8 +41,11 @@ ROOT / "docs/demo.md", ROOT / "docs/evals.md", ROOT / "docs/standards-and-roadmap.md", + ROOT / "docs/agent-plugin-compatibility.md", + ROOT / "docs/adr/0001-agent-plugin-and-skills-sh-coexistence.md", ROOT / "scripts/generate_demo.py", ROOT / "scripts/generate-distribution.py", + ROOT / "scripts/validate-agent-plugin.py", ROOT / "scripts/validate-evals.py", ROOT / "scripts/install-waza-ci.sh", ROOT / "evals/github-build-or-reuse/eval.yaml", diff --git a/skills/github-build-or-reuse/SKILL.md b/skills/github-build-or-reuse/SKILL.md index 96561c6..f93aeb2 100644 --- a/skills/github-build-or-reuse/SKILL.md +++ b/skills/github-build-or-reuse/SKILL.md @@ -5,7 +5,7 @@ license: MIT compatibility: "Requires network access and a GitHub search/API/CLI or equivalent web research capability for live repository due diligence." metadata: author: "GitHub Community Spain" - version: "1.2.1" + version: "1.2.2" --- # GitHub Build or Reuse