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

@ -34,12 +34,10 @@ REPO_ROOT = Path(__file__).resolve().parent.parent
VERSION_FILE = REPO_ROOT / "hermes_cli" / "__init__.py"
PYPROJECT_FILE = REPO_ROOT / "pyproject.toml"
# ACP Registry assets that must stay version-locked with pyproject.toml.
# tests/acp/test_registry_manifest.py enforces this lockstep, so the release
# bump touches all four files atomically.
# ACP Registry manifest must stay version-locked with pyproject.toml.
# tests/acp/test_registry_manifest.py enforces this lockstep so the release
# bump touches both files atomically.
ACP_REGISTRY_MANIFEST = REPO_ROOT / "acp_registry" / "agent.json"
ACP_NPM_PACKAGE_JSON = REPO_ROOT / "packages" / "hermes-agent-acp" / "package.json"
ACP_NPM_LAUNCHER = REPO_ROOT / "packages" / "hermes-agent-acp" / "bin" / "hermes-agent-acp.js"
# ──────────────────────────────────────────────────────────────────────
# Git email → GitHub username mapping
@ -1168,38 +1166,23 @@ def update_version_files(semver: str, calver_date: str):
def _update_acp_registry_versions(semver: str) -> None:
"""Bump the ACP Registry manifest, npm package, and launcher in lockstep.
"""Bump the ACP Registry manifest's version + uvx package pin in lockstep
with pyproject.
Skips silently if any of the files are missing the ACP Registry assets
landed mid-cycle and older release branches may not have them.
Skips silently if the manifest is missing older release branches predate
the ACP Registry assets.
"""
if ACP_REGISTRY_MANIFEST.exists():
manifest = json.loads(ACP_REGISTRY_MANIFEST.read_text(encoding="utf-8"))
manifest["version"] = semver
npx = manifest.get("distribution", {}).get("npx", {})
if "package" in npx:
npx["package"] = f"@nousresearch/hermes-agent-acp@{semver}"
uvx = manifest.get("distribution", {}).get("uvx", {})
if "package" in uvx:
uvx["package"] = f"hermes-agent[acp]=={semver}"
# Preserve trailing newline + 2-space indent the file already uses.
ACP_REGISTRY_MANIFEST.write_text(
json.dumps(manifest, indent=2) + "\n", encoding="utf-8"
)
if ACP_NPM_PACKAGE_JSON.exists():
package = json.loads(ACP_NPM_PACKAGE_JSON.read_text(encoding="utf-8"))
package["version"] = semver
ACP_NPM_PACKAGE_JSON.write_text(
json.dumps(package, indent=2) + "\n", encoding="utf-8"
)
if ACP_NPM_LAUNCHER.exists():
launcher = ACP_NPM_LAUNCHER.read_text(encoding="utf-8")
launcher = re.sub(
r"const HERMES_AGENT_VERSION\s*=\s*'[^']+';",
f"const HERMES_AGENT_VERSION = '{semver}';",
launcher,
)
ACP_NPM_LAUNCHER.write_text(launcher, encoding="utf-8")
def build_release_artifacts(semver: str) -> list[Path]:
"""Build sdist/wheel artifacts for the current release.