From b22f4195bf119566a173dae8704b3cad3b27b7b4 Mon Sep 17 00:00:00 2001
From: galuszkm
Date: Tue, 24 Mar 2026 01:25:24 +0100
Subject: [PATCH] feat: Add CLI and enhance documentation
- Updated `config.yaml` in the streaming example to use `wire_event_queue()` instead of `make_event_queue()`.
- Simplified installation instructions in the README for the agent factory example.
- Improved the main README to clarify the purpose of hooks in the hooks example.
- Added license, authors, and keywords to `pyproject.toml` for better package metadata.
- Introduced a command-line interface (CLI) in `cli.py` for validating and loading YAML configurations.
- Added type hints and documentation for agent and orchestration resolvers.
- Enhanced error handling and logging in the `ToolNameSanitizer` hook.
- Updated unit tests for the new CLI functionality, ensuring comprehensive coverage for both success and failure paths.
- Added support for multi-file configuration in the CLI.
- Included versioning and additional metadata in JSON outputs for CLI commands.
---
.github/copilot-instructions.md | 4 +-
AGENTS.md | 4 +-
LICENSE | 1 -
README.md | 40 +-
SUPPORT.md | 3 +
docs/index.html | 2 +-
examples/10_nested/README.md | 26 +-
examples/12_streaming/config.yaml | 2 +-
examples/14_agent_factory/README.md | 2 +-
examples/README.md | 4 +-
pyproject.toml | 27 +-
src/strands_compose/cli.py | 427 +++++++++++++++
.../config/resolvers/agents.py | 8 +
.../resolvers/orchestrations/__init__.py | 8 +
.../resolvers/orchestrations/builders.py | 2 +
.../hooks/tool_name_sanitizer.py | 9 +-
src/strands_compose/py.typed | 0
tests/unit/test_cli.py | 501 ++++++++++++++++++
tests/unit/test_event_queue.py | 15 +-
uv.lock | 2 -
20 files changed, 1045 insertions(+), 42 deletions(-)
create mode 100644 src/strands_compose/cli.py
create mode 100644 src/strands_compose/py.typed
create mode 100644 tests/unit/test_cli.py
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 6e1b9ee..decb91f 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -68,12 +68,12 @@ uv run just format # auto-format with ruff
```
src/strands_compose/
-├── __init__.py # Public API — load(), ComposeResult
+├── __init__.py # Public API — load(), ResolvedConfig
├── models.py # Pydantic config models (AgentConfig, ModelConfig, …)
├── types.py # Shared type aliases
├── utils.py # Miscellaneous helpers
├── exceptions.py # Custom exception hierarchy
-├── wire.py # Final assembly — wires all resolved objects into ComposeResult
+├── wire.py # Final assembly — wires all resolved objects into ResolvedConfig
├── config/ # YAML loading, validation, interpolation
│ ├── schema.py # JSON-schema for config validation
│ ├── interpolation.py # ${VAR:-default} interpolation
diff --git a/AGENTS.md b/AGENTS.md
index 2b2acef..5cd587c 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -68,12 +68,12 @@ uv run just format # auto-format with ruff
```
src/strands_compose/
-├── __init__.py # Public API — load(), ComposeResult
+├── __init__.py # Public API — load(), ResolvedConfig
├── models.py # Pydantic config models (AgentConfig, ModelConfig, …)
├── types.py # Shared type aliases
├── utils.py # Miscellaneous helpers
├── exceptions.py # Custom exception hierarchy
-├── wire.py # Final assembly — wires all resolved objects into ComposeResult
+├── wire.py # Final assembly — wires all resolved objects into ResolvedConfig
├── config/ # YAML loading, validation, interpolation
│ ├── schema.py # JSON-schema for config validation
│ ├── interpolation.py # ${VAR:-default} interpolation
diff --git a/LICENSE b/LICENSE
index 67db858..dd5b3a5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,3 @@
-
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
diff --git a/README.md b/README.md
index e3f5e74..5dc0741 100644
--- a/README.md
+++ b/README.md
@@ -9,12 +9,12 @@
-
+
> [!IMPORTANT]
-> Community project — not affiliated with AWS or the strands-agents team. Bugs here? [Open an issue](https://github.com/galuszkm/strands-compose/issues). Bugs in the underlying SDK? Head to [strands-agents](https://github.com/strands-agents/sdk-python).
+> Community project — not affiliated with AWS or the strands-agents team. Bugs here? [Open an issue](https://github.com/strands-compose/sdk-python/issues). Bugs in the underlying SDK? Head to [strands-agents](https://github.com/strands-agents/sdk-python).
## What is this?
@@ -180,13 +180,16 @@ Split large configs across files — models in one, agents in another, MCP in a
## Getting started
+Install with [uv](https://docs.astral.sh/uv/):
+
```bash
-git clone https://github.com/strands-compose/sdk-python
-cd sdk-python
-uv sync --all-groups --all-extras
+uv add strands-compose # Bedrock (default)
+uv add strands-compose[ollama] # + Ollama
+uv add strands-compose[openai] # + OpenAI
+uv add strands-compose[gemini] # + Gemini
```
-Install from PyPI:
+Or with pip:
```bash
pip install strands-compose # Bedrock (default)
@@ -223,6 +226,27 @@ with resolved.mcp_lifecycle:
print(result)
```
+### CLI
+
+strands-compose ships a CLI to validate and debug configs without writing Python.
+
+**`check`** — fast, static validation (YAML syntax, schema, variable interpolation, cross-references). No side-effects, safe for CI. Will **not** catch runtime issues like bad credentials, unreachable MCP servers, or missing Python modules.
+
+```bash
+strands-compose check config.yaml
+strands-compose check base.yaml agents.yaml # merge multiple files
+strands-compose check config.yaml --json # JSON output for scripts
+strands-compose check config.yaml --quiet # exit code only
+```
+
+**`load`** *(recommended)* — full end-to-end validation. Builds real Python objects, starts MCP servers, and probes connectivity. Catches everything `check` catches plus import errors, auth failures, and MCP health issues.
+
+```bash
+strands-compose load config.yaml
+strands-compose load config.yaml --json
+strands-compose load config.yaml --quiet
+```
+
---
## Examples
@@ -323,7 +347,7 @@ orchestrations:
connections:
- agent: content_team # Nested swarm as a delegate tool
description: "Content creation team."
- - agent: qa_bot # Neasted agent as a delegate tool
+ - agent: qa_bot # Nested agent as a delegate tool
description: "Quality assurance."
entry: team_leader
@@ -363,7 +387,7 @@ async def main():
asyncio.run(main())
```
-Event types: `TOKEN`, `REASONING`, `TOOL_START`, `TOOL_END`, `NODE_START`, `NODE_STOP`, `HANDOFF`, `COMPLETE` — each carrying `{type, agent_name, timestamp, data}`. Enough for a real-time frontend, a log aggregator, or a debugging dashboard. The `AnsiRenderer` gives you coloured terminal output out of the box — agent names, tool calls, reasoning traces, all streaming live.
+Event types: `AGENT_START`, `TOKEN`, `REASONING`, `TOOL_START`, `TOOL_END`, `NODE_START`, `NODE_STOP`, `HANDOFF`, `COMPLETE`, `MULTIAGENT_START`, `MULTIAGENT_COMPLETE`, `ERROR` — each carrying `{type, agent_name, timestamp, data}`. Enough for a real-time frontend, a log aggregator, or a debugging dashboard. The `AnsiRenderer` gives you coloured terminal output out of the box — agent names, tool calls, reasoning traces, all streaming live.
---
diff --git a/SUPPORT.md b/SUPPORT.md
index 42007a0..da902f1 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -20,6 +20,9 @@ If you encounter a bug or have a feature request:
## Security
If you discover a potential security issue, please see [SECURITY.md](SECURITY.md).
+
+## Troubleshooting
+
- If you see tool name errors, ensure the sanitizer is included in your hooks list
**Import errors:**
diff --git a/docs/index.html b/docs/index.html
index 7cd3dd1..6d74499 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -3,7 +3,7 @@
- strands Compose
+ Strands Compose