diff --git a/.github/workflows/sync-registry.yml b/.github/workflows/sync-registry.yml new file mode 100644 index 00000000..8dfb90b7 --- /dev/null +++ b/.github/workflows/sync-registry.yml @@ -0,0 +1,72 @@ +name: Sync Registry Docs + +on: + # Allow manual trigger + workflow_dispatch: + + # Run hourly to pick up registry changes + schedule: + - cron: "15 * * * *" # Every hour at :15 + +permissions: + contents: write + pull-requests: write + +jobs: + sync: + name: Sync Registry Documentation + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Set up Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: "3.11" + + - name: Set up Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: latest + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Generate registry docs + run: python scripts/generate_registry_docs.py + + - name: Format generated files + run: npx prettier --write docs/registry/ + + - name: Check for changes + id: changes + run: | + if git diff --quiet docs/registry/index.mdx; then + echo "changed=false" >> $GITHUB_OUTPUT + else + echo "changed=true" >> $GITHUB_OUTPUT + fi + + - name: Create Pull Request + id: cpr + if: steps.changes.outputs.changed == 'true' + uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6 + with: + commit-message: "docs: update registry agents" + title: "docs: update registry agents" + body: | + This PR updates the registry documentation with the latest agents from the ACP Registry CDN. + + Auto-generated by the sync-registry workflow. + branch: auto/sync-registry + delete-branch: true + labels: documentation + + - name: Enable auto-merge + if: steps.cpr.outputs.pull-request-number + run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/docs/docs.json b/docs/docs.json index 0214a8bc..4c2db7e3 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -95,6 +95,10 @@ "libraries/typescript", "libraries/community" ] + }, + { + "group": "Registry", + "pages": ["registry/index"] } ] }, diff --git a/docs/registry/_agents.mdx b/docs/registry/_agents.mdx new file mode 100644 index 00000000..c6d08151 --- /dev/null +++ b/docs/registry/_agents.mdx @@ -0,0 +1,58 @@ +--- +title: Official ACP Registry +description: Discover Agent Client Protocol agents +--- + + + +The ACP Agent Registry is a curated collection of agents implementing the Agent Client Protocol. + +## Available Agents + +$$AGENTS_CARDS$$ + + + **Work in Progress**: This registry is under active development. Format and + contents may change. + + + + This registry only includes agents that support + [authentication](/rfds/auth-methods). Agents must implement auth flows to be + listed here. Not all ACP-compatible agents are listed yet—as soon as they're + ready, we'll be happy to add them. + + + + The registry is hosted at + [github.com/agentclientprotocol/registry](https://github.com/agentclientprotocol/registry). + Visit the repository to contribute your own agent. + + +## Using the Registry + +Clients can fetch the registry programmatically: + +```bash +curl https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json +``` + +The registry JSON contains all agent metadata including distribution information for automatic installation. + +## Contributing + +To add your agent to the registry: + +1. Fork the [registry repository](https://github.com/agentclientprotocol/registry) +2. Create a folder with your agent's ID (lowercase, hyphens allowed) +3. Add an `agent.json` file following the [schema](https://github.com/agentclientprotocol/registry/blob/main/agent.schema.json) +4. Optionally add an `icon.svg` (16x16 recommended) +5. Submit a pull request + +See the [contributing guide](https://github.com/agentclientprotocol/registry/blob/main/CONTRIBUTING.md) for details. diff --git a/docs/registry/index.mdx b/docs/registry/index.mdx new file mode 100644 index 00000000..27191f57 --- /dev/null +++ b/docs/registry/index.mdx @@ -0,0 +1,316 @@ +--- +title: Official ACP Registry +description: Discover Agent Client Protocol agents +--- + + + +The ACP Agent Registry is a curated collection of agents implementing the Agent Client Protocol. + +## Available Agents + + + + + + + } + href="https://github.com/augmentcode/auggie-zed-extension" + > + Augment Code's powerful software agent, backed by industry-leading + context engine + + 0.14.0 + + + + + + } + href="https://github.com/zed-industries/codex-acp" + > + ACP adapter for OpenAI's coding assistant + + 0.9.0 + + + + + + } + > + Factory Droid - AI coding agent powered by Factory AI + + 0.52.0 + + + + + + } + href="https://github.com/google-gemini/gemini-cli" + > + Google's official CLI for Gemini + + 0.25.2 + + + + + + + + } + href="https://github.com/github/copilot-language-server-release" + > + GitHub's AI pair programmer + + 1.413.0 + + + + + + + + + + + + + + + } + href="https://github.com/mistralai/mistral-vibe" + > + Mistral's open-source coding assistant + + 1.3.5 + + + + + + } + href="https://github.com/sst/opencode" + > + The open source coding agent + + 1.1.34 + + + + + + } + href="https://github.com/QwenLM/qwen-code" + > + Alibaba's Qwen coding assistant + + 0.7.2 + + + + + + **Work in Progress**: This registry is under active development. Format and + contents may change. + + + + This registry only includes agents that support + [authentication](/rfds/auth-methods). Agents must implement auth flows to be + listed here. Not all ACP-compatible agents are listed yet—as soon as they're + ready, we'll be happy to add them. + + + + The registry is hosted at + [github.com/agentclientprotocol/registry](https://github.com/agentclientprotocol/registry). + Visit the repository to contribute your own agent. + + +## Using the Registry + +Clients can fetch the registry programmatically: + +```bash +curl https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json +``` + +The registry JSON contains all agent metadata including distribution information for automatic installation. + +## Contributing + +To add your agent to the registry: + +1. Fork the [registry repository](https://github.com/agentclientprotocol/registry) +2. Create a folder with your agent's ID (lowercase, hyphens allowed) +3. Add an `agent.json` file following the [schema](https://github.com/agentclientprotocol/registry/blob/main/agent.schema.json) +4. Optionally add an `icon.svg` (16x16 recommended) +5. Submit a pull request + +See the [contributing guide](https://github.com/agentclientprotocol/registry/blob/main/CONTRIBUTING.md) for details. diff --git a/package.json b/package.json index 511970ac..c3b1b2d7 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "format:check": "prettier --check . && cargo fmt -- --check", "spellcheck": "./scripts/spellcheck.sh", "spellcheck:fix": "./scripts/spellcheck.sh --write-changes", + "generate:registry": "python3 scripts/generate_registry_docs.py", "check": "cargo clippy --all-features && npm run format:check && npm run spellcheck && cargo test --all-features", "docs": "cd docs && npx mint dev" }, diff --git a/scripts/generate_registry_docs.py b/scripts/generate_registry_docs.py new file mode 100755 index 00000000..4f6a1950 --- /dev/null +++ b/scripts/generate_registry_docs.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 +""" +Generates registry documentation from the ACP Agent Registry CDN. + +This script fetches the registry.json from the CDN and generates +an MDX page with agent cards for the documentation site. + +Usage: + python scripts/generate_registry_docs.py + +Environment variables: + REGISTRY_URL: Override the default CDN URL (optional) +""" +from __future__ import annotations + +import json +import os +import re +import urllib.request +from pathlib import Path + +REGISTRY_URL = os.environ.get( + "REGISTRY_URL", + "https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json", +) +ICON_BASE_URL = "https://cdn.agentclientprotocol.com/registry/v1/latest" + +ROOT = Path(__file__).resolve().parents[1] +DOCS_DIR = ROOT / "docs" +TEMPLATE_PATH = DOCS_DIR / "registry" / "_agents.mdx" +OUTPUT_PATH = DOCS_DIR / "registry" / "index.mdx" +PLACEHOLDER = "$$AGENTS_CARDS$$" + +# SVG attribute mappings for JSX compatibility +SVG_ATTR_REPLACEMENTS = { + "fill-rule": "fillRule", + "clip-rule": "clipRule", + "clip-path": "clipPath", + "stroke-width": "strokeWidth", + "stroke-linecap": "strokeLinecap", + "stroke-linejoin": "strokeLinejoin", + "stroke-miterlimit": "strokeMiterlimit", + "stroke-dasharray": "strokeDasharray", + "stroke-dashoffset": "strokeDashoffset", + "stroke-opacity": "strokeOpacity", + "fill-opacity": "fillOpacity", + "stop-color": "stopColor", + "stop-opacity": "stopOpacity", + "vector-effect": "vectorEffect", +} + + +def _escape_html(text: str) -> str: + return ( + text.replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace('"', """) + .replace("'", "'") + ) + + +def _escape_text(text: str) -> str: + return _escape_html(text).replace("\n", " ") + + +def _sanitize_svg(svg: str) -> str: + """Sanitize SVG for JSX embedding with currentColor support.""" + svg = svg.strip() + # Remove existing width/height/class attributes + svg = re.sub(r'\s(width|height)="[^"]*"', "", svg) + svg = re.sub(r'\sclass="[^"]*"', "", svg) + # Add JSX-compatible attributes + svg = re.sub( + r" bytes: + """Make HTTP request with proper headers.""" + req = urllib.request.Request(url, headers={"User-Agent": "ACP-Registry-Docs/1.0"}) + with urllib.request.urlopen(req, timeout=timeout) as response: + return response.read() + + +def _fetch_registry() -> dict: + """Fetch registry.json from CDN.""" + print(f"Fetching registry from {REGISTRY_URL}...") + data = json.loads(_make_request(REGISTRY_URL).decode("utf-8")) + print(f"Fetched {len(data.get('agents', []))} agents") + return data + + +def _fetch_icon_svg(agent_id: str) -> str: + """Fetch and sanitize SVG icon from CDN.""" + url = f"{ICON_BASE_URL}/{agent_id}.svg" + try: + svg = _make_request(url, timeout=10).decode("utf-8") + return _sanitize_svg(svg) + except Exception as e: + print(f"Warning: Could not fetch icon for {agent_id}: {e}") + return "" + + +def _render_agent_cards(agents: list[dict]) -> str: + """Render agent cards as MDX components.""" + # Sort agents by name + agents = sorted(agents, key=lambda a: a.get("name", "").lower()) + + lines: list[str] = [""] + + for agent in agents: + agent_id = agent.get("id", "-") + name = agent.get("name", agent_id) + description = _escape_text(agent.get("description", "-")) + version = _escape_text(agent.get("version", "-")) + repository = agent.get("repository", "") + icon_svg = _fetch_icon_svg(agent_id) + + lines.append(" ") + lines.append(f" {description}") + version_text = version if version not in ("", "-") else "version unknown" + lines.append(f" {_escape_text(version_text)}") + lines.append(" ") + + lines.append("") + return "\n".join(lines) + + +def main() -> None: + # Ensure output directory exists + OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True) + + # Check if template exists + if not TEMPLATE_PATH.exists(): + print(f"Error: Template file not found at {TEMPLATE_PATH}") + print("Please create the template file first.") + raise SystemExit(1) + + # Fetch registry data + registry = _fetch_registry() + agents = registry.get("agents", []) + + if not agents: + print("Warning: No agents found in registry") + + # Generate output + template = TEMPLATE_PATH.read_text() + cards = _render_agent_cards(agents) + output = template.replace(PLACEHOLDER, cards) + + # Write output + OUTPUT_PATH.write_text(output) + print(f"Generated {OUTPUT_PATH}") + + +if __name__ == "__main__": + main()
+ 0.14.0 +
0.14.0
+ 0.9.0 +
0.9.0
+ 0.52.0 +
0.52.0
+ 0.25.2 +
0.25.2
+ 1.413.0 +
1.413.0
+ 1.3.5 +
1.3.5
+ 1.1.34 +
1.1.34
+ 0.7.2 +
0.7.2
{_escape_text(version_text)}