From 50f7b62783e125dbeb91833c9b1c1309538d52fe Mon Sep 17 00:00:00 2001 From: "helen@cloud" Date: Mon, 23 Mar 2026 04:59:37 -0400 Subject: [PATCH 1/2] docs(cli): make root command canonical and keep serve as alias (#295) --- README.md | 4 +++- docs/guide.md | 4 +++- src/opencode_a2a/cli.py | 14 +++++++++++--- tests/server/test_cli.py | 4 +++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 923f652..2066a84 100644 --- a/README.md +++ b/README.md @@ -77,9 +77,11 @@ A2A_HOST=127.0.0.1 \ A2A_PORT=8000 \ A2A_PUBLIC_URL=http://127.0.0.1:8000 \ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \ -opencode-a2a serve +opencode-a2a ``` +`opencode-a2a serve` remains available as a backward-compatible alias. + Verify that the service is up: ```bash diff --git a/docs/guide.md b/docs/guide.md index 60dfba6..56cb5b4 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -154,9 +154,11 @@ A2A_HOST=127.0.0.1 \ A2A_PORT=8000 \ A2A_PUBLIC_URL=http://127.0.0.1:8000 \ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \ -opencode-a2a serve +opencode-a2a ``` +`opencode-a2a serve` remains available as a backward-compatible alias. + ## Troubleshooting Provider Auth State If one deployment works while another fails against the same upstream provider, diff --git a/src/opencode_a2a/cli.py b/src/opencode_a2a/cli.py index 68147d3..c60ec02 100644 --- a/src/opencode_a2a/cli.py +++ b/src/opencode_a2a/cli.py @@ -53,7 +53,12 @@ def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( prog="opencode-a2a", description=( - "OpenCode A2A runtime. Deployment supervision is intentionally left to the operator." + "OpenCode A2A runtime. Run without a subcommand to start the service." + " Deployment supervision is intentionally left to the operator." + ), + epilog=( + "Running `opencode-a2a` with no subcommand starts the runtime." + " `serve` is kept as a backward-compatible alias." ), formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) @@ -66,8 +71,11 @@ def build_parser() -> argparse.ArgumentParser: subparsers = parser.add_subparsers(dest="command") subparsers.add_parser( "serve", - help="Start the OpenCode A2A runtime using environment-based settings.", - description="Start the OpenCode A2A runtime using environment-based settings.", + help="Backward-compatible alias for starting the OpenCode A2A runtime.", + description=( + "Backward-compatible alias for starting the OpenCode A2A runtime" + " using environment-based settings." + ), ) call_parser = subparsers.add_parser( diff --git a/tests/server/test_cli.py b/tests/server/test_cli.py index 614bd81..c3e3eae 100644 --- a/tests/server/test_cli.py +++ b/tests/server/test_cli.py @@ -15,6 +15,8 @@ def test_cli_help_does_not_require_runtime_settings(capsys: pytest.CaptureFixtur assert excinfo.value.code == 0 help_text = capsys.readouterr().out assert "serve" in help_text + assert "Run without a subcommand to start the service." in help_text + assert "backward-compatible alias" in help_text assert "deploy-release" not in help_text assert "init-release-system" not in help_text assert "uninstall-instance" not in help_text @@ -29,7 +31,7 @@ def test_cli_serve_help_exposes_runtime_contract( assert excinfo.value.code == 0 help_text = capsys.readouterr().out - assert "Start the OpenCode A2A runtime using environment-based settings." in help_text + assert "Backward-compatible alias for starting the OpenCode A2A runtime" in help_text def test_cli_version_does_not_require_runtime_settings( From 9aa5605073977fe9ce1635b6983a118739d274c8 Mon Sep 17 00:00:00 2001 From: "helen@cloud" Date: Mon, 23 Mar 2026 05:10:29 -0400 Subject: [PATCH 2/2] refactor(cli): remove redundant serve subcommand (#295) --- README.md | 2 -- docs/guide.md | 2 -- src/opencode_a2a/cli.py | 16 ---------------- tests/server/test_cli.py | 21 +++++---------------- 4 files changed, 5 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 2066a84..d54dd8a 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,6 @@ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \ opencode-a2a ``` -`opencode-a2a serve` remains available as a backward-compatible alias. - Verify that the service is up: ```bash diff --git a/docs/guide.md b/docs/guide.md index 56cb5b4..300014c 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -157,8 +157,6 @@ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \ opencode-a2a ``` -`opencode-a2a serve` remains available as a backward-compatible alias. - ## Troubleshooting Provider Auth State If one deployment works while another fails against the same upstream provider, diff --git a/src/opencode_a2a/cli.py b/src/opencode_a2a/cli.py index c60ec02..097bc51 100644 --- a/src/opencode_a2a/cli.py +++ b/src/opencode_a2a/cli.py @@ -56,10 +56,6 @@ def build_parser() -> argparse.ArgumentParser: "OpenCode A2A runtime. Run without a subcommand to start the service." " Deployment supervision is intentionally left to the operator." ), - epilog=( - "Running `opencode-a2a` with no subcommand starts the runtime." - " `serve` is kept as a backward-compatible alias." - ), formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) parser.add_argument( @@ -69,14 +65,6 @@ def build_parser() -> argparse.ArgumentParser: ) subparsers = parser.add_subparsers(dest="command") - subparsers.add_parser( - "serve", - help="Backward-compatible alias for starting the OpenCode A2A runtime.", - description=( - "Backward-compatible alias for starting the OpenCode A2A runtime" - " using environment-based settings." - ), - ) call_parser = subparsers.add_parser( "call", @@ -103,10 +91,6 @@ def main(argv: Sequence[str] | None = None) -> int: return 0 namespace = parser.parse_args(args) - if namespace.command == "serve": - serve_main() - return 0 - if namespace.command == "call": return asyncio.run(run_call(namespace.agent_url, namespace.text, namespace.token)) diff --git a/tests/server/test_cli.py b/tests/server/test_cli.py index c3e3eae..13ffd02 100644 --- a/tests/server/test_cli.py +++ b/tests/server/test_cli.py @@ -14,24 +14,20 @@ def test_cli_help_does_not_require_runtime_settings(capsys: pytest.CaptureFixtur assert excinfo.value.code == 0 help_text = capsys.readouterr().out - assert "serve" in help_text assert "Run without a subcommand to start the service." in help_text - assert "backward-compatible alias" in help_text + assert "{call}" in help_text + assert "serve" not in help_text assert "deploy-release" not in help_text assert "init-release-system" not in help_text assert "uninstall-instance" not in help_text serve_mock.assert_not_called() -def test_cli_serve_help_exposes_runtime_contract( - capsys: pytest.CaptureFixture[str], -) -> None: +def test_cli_serve_subcommand_is_rejected() -> None: with pytest.raises(SystemExit) as excinfo: - cli.main(["serve", "--help"]) + cli.main(["serve"]) - assert excinfo.value.code == 0 - help_text = capsys.readouterr().out - assert "Backward-compatible alias for starting the OpenCode A2A runtime" in help_text + assert excinfo.value.code == 2 def test_cli_version_does_not_require_runtime_settings( @@ -53,13 +49,6 @@ def test_cli_defaults_to_serve_when_no_subcommand() -> None: serve_mock.assert_called_once_with() -def test_cli_serve_subcommand_invokes_runtime() -> None: - with mock.patch("opencode_a2a.cli.serve_main") as serve_mock: - assert cli.main(["serve"]) == 0 - - serve_mock.assert_called_once_with() - - def test_cli_call_uses_outbound_bearer_env_default() -> None: with mock.patch.dict( "os.environ",