Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions acp_registry/agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
"authors": ["Nous Research"],
"license": "MIT",
"distribution": {
"npx": {
"package": "@nousresearch/hermes-agent-acp@0.13.0"
"uvx": {
"package": "hermes-agent[acp]==0.13.0",
"args": ["hermes-acp"]
}
}
}
97 changes: 0 additions & 97 deletions docs/plans/acp-registry-zed-integration.md

This file was deleted.

26 changes: 0 additions & 26 deletions packages/hermes-agent-acp/README.md

This file was deleted.

66 changes: 0 additions & 66 deletions packages/hermes-agent-acp/bin/hermes-agent-acp.js

This file was deleted.

24 changes: 0 additions & 24 deletions packages/hermes-agent-acp/package.json

This file was deleted.

23 changes: 0 additions & 23 deletions packages/hermes-agent-acp/test/launcher.test.js

This file was deleted.

37 changes: 10 additions & 27 deletions scripts/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,10 @@
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
Expand Down Expand Up @@ -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.
Expand Down
34 changes: 14 additions & 20 deletions tests/acp/test_registry_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()}"
)


Expand Down
Loading
Loading