feat(acp-registry): switch to uvx distribution, drop npm launcher

The ACP Registry schema supports uvx as a first-class distribution method
alongside npx and binary. Pointing the registry directly at the existing
hermes-agent PyPI release removes:

- the @nousresearch npm scope (we don't own it)
- a separate npm publish step on every weekly release
- 90 lines of Node launcher + tests in packages/hermes-agent-acp/

The Zed registry now installs Hermes via:

  uvx --from 'hermes-agent[acp]==<version>' hermes-acp

This is the same command the npm launcher was shelling out to anyway, so
end-user behavior is unchanged. Registry CI validates the PyPI URL +
version-pin exact match automatically.

Changes:
- acp_registry/agent.json: distribution.npx -> distribution.uvx
- delete packages/hermes-agent-acp/ entirely
- scripts/release.py: drop npm-launcher bump paths, keep manifest lockstep
- tests/acp/test_registry_manifest.py: assert uvx shape + version pin
- tests/scripts/test_release_acp_registry.py: rewrite for uvx-only shape
- docs (user-guide + dev-guide): drop all npm-launcher references
- delete docs/plans/acp-registry-zed-integration.md (stale, npm-shaped)

Validated against agentclientprotocol/registry agent.schema.json via
jsonschema. hermes-agent==0.13.0 is already live on PyPI.
This commit is contained in:
teknium1 2026-05-14 22:05:39 -07:00 committed by Teknium
parent 5af672c753
commit c8c6ce1731
11 changed files with 56 additions and 360 deletions

View file

@ -39,36 +39,30 @@ def test_agent_json_matches_official_registry_required_fields():
assert set(data["distribution"]) <= ALLOWED_DISTRIBUTIONS
def test_agent_json_uses_npx_distribution_without_local_command_fields():
def test_agent_json_uses_uvx_distribution_without_local_command_fields():
data = _manifest()
assert set(data["distribution"]) == {"npx"}
assert set(data["distribution"]["npx"]) == {"package"}
assert data["distribution"]["npx"]["package"] == (
f"@nousresearch/hermes-agent-acp@{data['version']}"
)
assert set(data["distribution"]) == {"uvx"}
uvx = data["distribution"]["uvx"]
# Schema allows {package, args, env}; we use {package, args}.
assert set(uvx) <= {"package", "args", "env"}
assert "package" in uvx
assert uvx["package"] == f"hermes-agent[acp]=={data['version']}"
assert uvx["args"] == ["hermes-acp"]
# Old command-shape fields must not leak back in.
assert "type" not in data["distribution"]
assert "command" not in data["distribution"]
assert "args" not in data["distribution"]
def test_agent_json_version_matches_pyproject():
assert _manifest()["version"] == _pyproject_version()
def test_npm_launcher_versions_match_pyproject_and_manifest():
version = _pyproject_version()
package = json.loads(
(ROOT / "packages" / "hermes-agent-acp" / "package.json").read_text(encoding="utf-8")
)
launcher = (ROOT / "packages" / "hermes-agent-acp" / "bin" / "hermes-agent-acp.js").read_text(
encoding="utf-8"
)
assert package["version"] == version
assert f"const HERMES_AGENT_VERSION = '{version}';" in launcher
assert _manifest()["distribution"]["npx"]["package"] == (
f"@nousresearch/hermes-agent-acp@{version}"
def test_agent_json_pins_uvx_package_to_pyproject_version():
"""The registry CI rejects ``@latest`` and floating pins; the manifest must
always reference the exact PyPI version listed in pyproject.toml."""
assert _manifest()["distribution"]["uvx"]["package"] == (
f"hermes-agent[acp]=={_pyproject_version()}"
)