From 8a5aa15cb7591009e908e2134362fcebadda7c8b Mon Sep 17 00:00:00 2001 From: Ben Brandt Date: Fri, 6 Feb 2026 14:20:11 +0100 Subject: [PATCH] Remove extensions from schema for now Since the relevant RFD is still in progress and the name may change, going to remove this for now to align with the current state of the RFD --- .github/workflows/build_registry.py | 84 +++++++++++------------------ AGENTS.md | 17 +++--- CONTRIBUTING.md | 43 ++++++++------- FORMAT.md | 9 ++-- README.md | 12 ++--- registry.schema.json | 11 +--- 6 files changed, 77 insertions(+), 99 deletions(-) diff --git a/.github/workflows/build_registry.py b/.github/workflows/build_registry.py index ef7e13c..04af74f 100644 --- a/.github/workflows/build_registry.py +++ b/.github/workflows/build_registry.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Build aggregated registry.json from individual agent and extension directories.""" +"""Build aggregated registry.json from individual agent directories.""" import json import os @@ -267,11 +267,9 @@ def validate_icon_monochrome(content: str) -> list[str]: reported_colors.add(style_stroke.group(1).strip()) # Check that currentColor is actually used (icons without fill default to black) - has_current_color = bool(re.search(r'currentColor', content, re.IGNORECASE)) + has_current_color = bool(re.search(r"currentColor", content, re.IGNORECASE)) if not has_current_color: - errors.append( - 'Icon must use currentColor for fills/strokes to support theming' - ) + errors.append("Icon must use currentColor for fills/strokes to support theming") # Deduplicate errors return list(dict.fromkeys(errors)) @@ -426,7 +424,9 @@ def validate_agent( ) # Check that all OS families have at least one platform - provided_os_families = {p.split("-")[0] for p in binary.keys() if p in VALID_PLATFORMS} + provided_os_families = { + p.split("-")[0] for p in binary.keys() if p in VALID_PLATFORMS + } missing_os_families = REQUIRED_OS_FAMILIES - provided_os_families if missing_os_families: errors.append( @@ -465,7 +465,7 @@ def process_entry( base_url: str, seen_ids: dict, ) -> tuple[dict | None, list[str]]: - """Process a single agent or extension entry. Returns (entry, errors).""" + """Process a single registry entry. Returns (entry, errors).""" entry_path = entry_dir / entry_file # Parse JSON with error handling @@ -475,7 +475,7 @@ def process_entry( except json.JSONDecodeError as e: return None, [f"{entry_dir.name}/{entry_file} is invalid JSON: {e}"] - # Validate entry (uses same schema for both agents and extensions) + # Validate entry validation_errors = validate_agent(entry, entry_dir.name, schema) if validation_errors: return None, [f"{entry_dir.name}/{entry_file} validation failed:"] + [ @@ -492,7 +492,7 @@ def process_entry( f" - {e}" for e in version_errors ] - # Check for duplicate IDs (across both agents and extensions) + # Check for duplicate IDs entry_id = entry["id"] if entry_id in seen_ids: return None, [ @@ -522,15 +522,14 @@ def process_entry( def build_registry(): - """Build registry.json from agent and extension directories.""" + """Build registry.json from agent directories.""" registry_dir = Path(__file__).parent.parent.parent base_url = get_base_url() agents = [] - extensions = [] seen_ids = {} has_errors = False - # Load schema for validation (used for both agents and extensions) + # Load schema for validation schema = load_schema(registry_dir) if schema and not HAS_JSONSCHEMA: print("Warning: jsonschema not installed, skipping schema validation") @@ -541,56 +540,32 @@ def build_registry(): continue agent_json_path = entry_dir / "agent.json" - extension_json_path = entry_dir / "extension.json" - - has_agent = agent_json_path.exists() - has_extension = extension_json_path.exists() - if has_agent and has_extension: - print(f"Error: {entry_dir.name}/ has both agent.json and extension.json") - has_errors = True + if not agent_json_path.exists(): + print(f"Warning: {entry_dir.name}/ has no agent.json, skipping") continue - if not has_agent and not has_extension: - print( - f"Warning: {entry_dir.name}/ has no agent.json or extension.json, skipping" - ) + entry, errors = process_entry( + entry_dir, "agent.json", "agent", schema, base_url, seen_ids + ) + if errors: + for error in errors: + print(f"Error: {error}") + has_errors = True continue - - if has_agent: - entry, errors = process_entry( - entry_dir, "agent.json", "agent", schema, base_url, seen_ids - ) - if errors: - for error in errors: - print(f"Error: {error}") - has_errors = True - continue - agents.append(entry) - print(f"Added agent: {entry['id']} v{entry['version']}") - else: - entry, errors = process_entry( - entry_dir, "extension.json", "extension", schema, base_url, seen_ids - ) - if errors: - for error in errors: - print(f"Error: {error}") - has_errors = True - continue - extensions.append(entry) - print(f"Added extension: {entry['id']} v{entry['version']}") + agents.append(entry) + print(f"Added agent: {entry['id']} v{entry['version']}") if has_errors: print("\nBuild failed due to validation errors") sys.exit(1) - if not agents and not extensions: - print("\nWarning: No agents or extensions found") + if not agents: + print("\nWarning: No agents found") registry = { "version": REGISTRY_VERSION, "agents": agents, - "extensions": extensions, } # Create dist directory @@ -608,15 +583,14 @@ def build_registry(): jetbrains_registry = { "version": REGISTRY_VERSION, "agents": [a for a in agents if a["id"] not in JETBRAINS_EXCLUDE_IDS], - "extensions": extensions, } jetbrains_output_path = dist_dir / "registry-for-jetbrains.json" with open(jetbrains_output_path, "w") as f: json.dump(jetbrains_registry, f, indent=2) f.write("\n") - # Copy icons to dist (for both agents and extensions) - for entry in agents + extensions: + # Copy icons to dist + for entry in agents: entry_id = entry["id"] icon_src = registry_dir / entry_id / "icon.svg" if icon_src.exists(): @@ -631,9 +605,11 @@ def build_registry(): schema_dst.write_bytes(schema_src.read_bytes()) jetbrains_agent_count = len(jetbrains_registry["agents"]) - print(f"\nBuilt dist/ with {len(agents)} agents and {len(extensions)} extensions") + print(f"\nBuilt dist/ with {len(agents)} agents") print(f" registry.json: {len(agents)} agents") - print(f" registry-for-jetbrains.json: {jetbrains_agent_count} agents (excluded: {', '.join(JETBRAINS_EXCLUDE_IDS)})") + print( + f" registry-for-jetbrains.json: {jetbrains_agent_count} agents (excluded: {', '.join(JETBRAINS_EXCLUDE_IDS)})" + ) if __name__ == "__main__": diff --git a/AGENTS.md b/AGENTS.md index 2e25dea..071cf62 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,25 +14,24 @@ python .github/workflows/build_registry.py ## Architecture -This is a registry of ACP (Agent Client Protocol) agents and extensions. The structure is: +This is a registry of ACP (Agent Client Protocol) agents. The structure is: ``` / ├── agent.json # Agent metadata and distribution info -├── extension.json # OR extension metadata (same schema as agent.json) └── icon.svg # Icon: 16x16 SVG, monochrome with currentColor (optional) ``` -Each directory contains either `agent.json` (for agents) or `extension.json` (for extensions), but not both. Extensions use the same schema as agents (`agent.schema.json`). - **Build process** (`.github/workflows/build_registry.py`): -1. Scans directories for `agent.json` or `extension.json` files + +1. Scans directories for `agent.json` files 2. Validates against `agent.schema.json` (JSON Schema) 3. Validates icons (16x16 SVG, monochrome with `currentColor`) -4. Aggregates into `dist/registry.json` with separate `agents` and `extensions` arrays +4. Aggregates into `dist/registry.json` 5. Copies icons to `dist/.svg` **CI/CD** (`.github/workflows/build-registry.yml`): + - PRs: Runs validation only - Push to main: Validates, then publishes versioned + `latest` GitHub releases @@ -52,6 +51,7 @@ Set `SKIP_URL_VALIDATION=1` to bypass URL checks during local development. ### Automated Updates Agent versions are automatically updated via `.github/workflows/update-versions.yml`: + - **Schedule:** Runs hourly (cron: `0 * * * *`) - **Scope:** Checks all agents in root and `_not_yet_unsupported/` - **Supported distributions:** `npx` (npm), `uvx` (PyPI), `binary` (GitHub releases) @@ -77,6 +77,7 @@ To update agents manually: 2. **For GitHub binaries** (`binary` distribution): Check latest release at `https://api.github.com/repos///releases/latest` Update `agent.json`: + - Update the `version` field - Update version in all distribution URLs (use replace-all for consistency) - For npm: update `package` field (e.g., `@google/gemini-cli@0.22.5`) @@ -95,6 +96,7 @@ Run build to validate: `uv run --with jsonschema .github/workflows/build_registr ## Icon Requirements Icons must be: + - **SVG format** (only `.svg` files accepted) - **16x16 dimensions** (via width/height attributes or viewBox) - **Monochrome using `currentColor`** - all fills and strokes must use `currentColor` or `none` @@ -102,6 +104,7 @@ Icons must be: Using `currentColor` enables icons to adapt to different themes (light/dark mode) automatically. **Valid example:** + ```svg @@ -109,6 +112,7 @@ Using `currentColor` enables icons to adapt to different themes (light/dark mode ``` **Invalid patterns:** + - Hardcoded colors: `fill="#FF5500"`, `fill="red"`, `stroke="rgb(0,0,0)"` - Missing currentColor: `fill` or `stroke` without `currentColor` @@ -117,6 +121,7 @@ Using `currentColor` enables icons to adapt to different themes (light/dark mode Agents must support ACP authentication. The CI verifies auth via `.github/workflows/verify_agents.py --auth-check`. **Requirements:** + - Return `authMethods` array in `initialize` response - At least one method must have type `"agent"` or `"terminal"` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5b0633f..dce04a8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to the ACP Registry -## Adding a New Agent or Extension +## Adding a New Agent 1. **Fork this repository** @@ -12,9 +12,7 @@ The directory name must match your entry's `id` field. -3. **Create `agent.json` or `extension.json`** - - Use `agent.json` for agents, `extension.json` for extensions. Both use the same schema. +3. **Create `agent.json`** ```json { @@ -40,6 +38,7 @@ - **Monochrome using `currentColor`** - enables theme support (light/dark mode) Example: + ```svg @@ -124,21 +123,21 @@ Supported platforms: `darwin-aarch64`, `darwin-x86_64`, `linux-aarch64`, `linux- ## Required Fields -| Field | Type | Description | -|-------|------|-------------| -| `id` | string | Unique identifier (lowercase, hyphens allowed) | -| `name` | string | Display name | -| `version` | string | Semantic version | -| `description` | string | Brief description | -| `distribution` | object | At least one distribution method | +| Field | Type | Description | +| -------------- | ------ | ---------------------------------------------- | +| `id` | string | Unique identifier (lowercase, hyphens allowed) | +| `name` | string | Display name | +| `version` | string | Semantic version | +| `description` | string | Brief description | +| `distribution` | object | At least one distribution method | ## Optional Fields -| Field | Type | Description | -|-------|------|-------------| -| `repository` | string | Source code URL | -| `authors` | array | List of author names/emails | -| `license` | string | SPDX license identifier | +| Field | Type | Description | +| ------------ | ------ | --------------------------- | +| `repository` | string | Source code URL | +| `authors` | array | List of author names/emails | +| `license` | string | SPDX license identifier | ## Automatic Version Updates @@ -152,9 +151,9 @@ You don't need to submit a PR for version bumps. ## Manual Updates -To manually update your agent or extension (e.g., changing description, adding platforms): +To manually update your agent (e.g., changing description, adding platforms): -1. Fork and update the `agent.json` or `extension.json` file +1. Fork and update the `agent.json` file 2. Submit a Pull Request 3. CI will validate and merge will trigger a new registry release @@ -171,7 +170,7 @@ Entries are validated against the [JSON Schema](agent.schema.json). - Must be lowercase letters, digits, and hyphens only - Must start with a letter - Must match the directory name -- Must be unique across all agents and extensions +- Must be unique across all agents ### Version Validation @@ -181,26 +180,31 @@ Entries are validated against the [JSON Schema](agent.schema.json). ### Distribution Validation **Structure:** + - At least one distribution method required (`binary`, `npx`, or `uvx`) - Binary distributions require `archive` and `cmd` fields per platform - Package distributions (`npx`, `uvx`) require `package` field **Platforms** (for binary): + - `darwin-aarch64`, `darwin-x86_64` - `linux-aarch64`, `linux-x86_64` - `windows-aarch64`, `windows-x86_64` **Cross-platform requirement** (for binary): + - Binary distributions must include builds for **all operating systems**: darwin (macOS), linux, and windows - At least one architecture per OS is required (e.g., `darwin-aarch64`, `linux-x86_64`, `windows-x86_64`) **Version matching:** + - Distribution versions must match the entry's `version` field - Binary URLs containing version (e.g., `/download/v1.0.0/`) are checked - npm package versions (`@scope/pkg@1.0.0`) are checked - PyPI package versions (`pkg==1.0.0` or `pkg@1.0.0`) are checked **No `latest` allowed:** + - Binary URLs must not contain `/latest/` - npm packages must not use `@latest` - PyPI packages must not use `@latest` @@ -233,6 +237,7 @@ python3 .github/workflows/verify_agents.py --auth-check ``` **What gets checked:** + - Agent must return `authMethods` in the `initialize` response - At least one method must have `type: "agent"` or `type: "terminal"` - See [AUTHENTICATION.md](AUTHENTICATION.md) for implementation details diff --git a/FORMAT.md b/FORMAT.md index a3a12ac..569625b 100644 --- a/FORMAT.md +++ b/FORMAT.md @@ -1,16 +1,15 @@ # Registry Format -The registry contains both agents and extensions: +The registry contains agents: ```json { "version": "1.0.0", - "agents": [...], - "extensions": [...] + "agents": [...] } ``` -Each entry (agent or extension) has the same structure: +Each agent has the following structure: ```json { @@ -46,7 +45,7 @@ Each entry (agent or extension) has the same structure: ## Distribution Types | Type | Description | Command | -|----------|-------------------------------|------------------------| +| -------- | ----------------------------- | ---------------------- | | `binary` | Platform-specific executables | Download, extract, run | | `npx` | npm packages | `npx [args]` | | `uvx` | PyPI packages via uv | `uvx [args]` | diff --git a/README.md b/README.md index 7461d40..289635e 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ > ⚠️ **Work in Progress**: This registry is under active development. Format and contents may change. -A registry of agents and extensions implementing the [Agent Client Protocol, ACP](https://github.com/agentclientprotocol/agent-client-protocol). +A registry of agents implementing the [Agent Client Protocol, ACP](https://github.com/agentclientprotocol/agent-client-protocol). -> **Authentication Required**: This registry maintains a curated list of **agents that support user authentication**. -> -> Users must be able to authenticate themselves with agents to use them. -> All agents are verified via CI to ensure they return valid `authMethods` in the ACP handshake. +> **Authentication Required**: This registry maintains a curated list of **agents that support user authentication**. +> +> Users must be able to authenticate themselves with agents to use them. +> All agents are verified via CI to ensure they return valid `authMethods` in the ACP handshake. > See [AUTHENTICATION.md](AUTHENTICATION.md) for implementation details and the [ACP auth methods proposal](https://github.com/agentclientprotocol/agent-client-protocol/blob/main/docs/rfds/auth-methods.mdx) for the specification. ## Included Agents @@ -36,7 +36,7 @@ https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json See [FORMAT.md](FORMAT.md) for the registry schema, distribution types, and platform targets. -## Adding an Agent or Extension +## Adding an Agent See [CONTRIBUTING.md](CONTRIBUTING.md) for instructions. diff --git a/registry.schema.json b/registry.schema.json index 05043ba..dbd3a7f 100644 --- a/registry.schema.json +++ b/registry.schema.json @@ -2,9 +2,9 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://cdn.agentclientprotocol.com/registry/v1/latest/registry.schema.json", "title": "ACP Agent Registry", - "description": "Schema for the aggregated ACP agent and extension registry index", + "description": "Schema for the aggregated ACP agent registry index", "type": "object", - "required": ["version", "agents", "extensions"], + "required": ["version", "agents"], "properties": { "version": { "type": "string", @@ -17,13 +17,6 @@ "items": { "$ref": "agent.schema.json" } - }, - "extensions": { - "type": "array", - "description": "List of registered extensions", - "items": { - "$ref": "agent.schema.json" - } } }, "additionalProperties": false