diff --git a/README.md b/README.md index dc8ced3..2de8717 100644 --- a/README.md +++ b/README.md @@ -24,19 +24,24 @@ import is safe. The plugin also logs the effective default at session start. ## Installation ```bash -# 1. Ensure piper-tts is installed -pip install piper-tts +# Install from the internal Hermes package registry +pip install hermes-piper-plugin -# 2. Install the plugin from the internal Hermes repo -hermes plugins install ssh://git@code.lazyworkhorse.net:2222/Hermes/hermes-piper-plugin.git - -# 3. Restart gateways to load the plugin +# Or install in editable mode for development +git clone https://code.lazyworkhorse.net/gortium/hermes-piper-plugin.git +cd hermes-piper-plugin +pip install -e . ``` +> **Note:** The plugin used to be installed via `hermes plugins install` from the +> old flat layout. It is now a proper pip package. The entry point +> `hermes_agent.plugins` is registered automatically when you install the +> package — Hermes discovers it on next startup. + ## Testing ```bash -cd /opt/data/projects/hermes-piper-plugin +cd /path/to/hermes-piper-plugin pip install pytest pyyaml python -m pytest tests/ -v ``` diff --git a/__init__.py b/hermes_piper_plugin/__init__.py similarity index 100% rename from __init__.py rename to hermes_piper_plugin/__init__.py diff --git a/plugin.yaml b/hermes_piper_plugin/plugin.yaml similarity index 100% rename from plugin.yaml rename to hermes_piper_plugin/plugin.yaml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..6c77dea --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,18 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "hermes-piper-plugin" +version = "1.0.0" +description = "Piper TTS plugin for Hermes Agent" +authors = [{name = "@gortium"}] +license = {text = "MIT"} +requires-python = ">=3.11" +dependencies = [] + +[project.entry-points.'hermes_agent.plugins'] +piper = "hermes_piper_plugin:register" + +[tool.setuptools.packages.find] +include = ["hermes_piper_plugin*", "tests*"] diff --git a/tests/test_piper_plugin.py b/tests/test_piper_plugin.py index 9c73d61..93cbf5b 100644 --- a/tests/test_piper_plugin.py +++ b/tests/test_piper_plugin.py @@ -62,7 +62,7 @@ def _clean_tools_tts(): def _load_plugin_module(name: str) -> types.ModuleType: """Load the plugin __init__.py as a fresh module with given name.""" - source = Path(__file__).resolve().parent.parent / "__init__.py" + source = Path(__file__).resolve().parent.parent / "hermes_piper_plugin" / "__init__.py" assert source.exists(), f"Plugin init not found at {source}" spec = importlib.util.spec_from_file_location(name, str(source)) mod = importlib.util.module_from_spec(spec) @@ -85,7 +85,7 @@ def plugin_dir() -> Path: @pytest.fixture def manifest(plugin_dir: Path) -> dict: - manifest_path = plugin_dir / "plugin.yaml" + manifest_path = plugin_dir / "hermes_piper_plugin" / "plugin.yaml" assert manifest_path.exists(), f"plugin.yaml not found at {manifest_path}" with open(manifest_path) as f: return yaml.safe_load(f) @@ -274,14 +274,14 @@ class TestPluginStructure: def test_required_files_exist(self, plugin_dir): """Plugin must have plugin.yaml, __init__.py, and README.md.""" - assert (plugin_dir / "plugin.yaml").exists(), "Missing plugin.yaml" - assert (plugin_dir / "__init__.py").exists(), "Missing __init__.py" + assert (plugin_dir / "hermes_piper_plugin" / "plugin.yaml").exists(), "Missing plugin.yaml" + assert (plugin_dir / "hermes_piper_plugin" / "__init__.py").exists(), "Missing __init__.py" assert (plugin_dir / "README.md").exists(), "Missing README.md" def test_init_has_register_function(self, plugin_dir): """__init__.py must expose a register() function.""" spec = importlib.util.spec_from_file_location( - "test_register_check", str(plugin_dir / "__init__.py") + "test_register_check", str(plugin_dir / "hermes_piper_plugin" / "__init__.py") ) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod)