From 86f720ee146eb25be884dc83eff31a0c6757a408 Mon Sep 17 00:00:00 2001 From: Molecule AI Core-DevOps Date: Sat, 9 May 2026 21:31:43 +0000 Subject: [PATCH] fix(build): install plugins_registry/ at wheel top level for bare imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue #152: claude-code workspace plugin adapter import fails with 'No module named plugins_registry'. Plugin adapter code (workspace-template-*) uses bare `from plugins_registry import ...` but molecule-runtime only shipped it at molecule_runtime/plugins_registry/ (the package namespace path). Fix: copy workspace/plugins_registry/ to the top level of the wheel in addition to molecule_runtime/plugins_registry/. Both copies coexist — the top-level one satisfies bare imports from plugin adapters, the nested one satisfies the rewritten `from molecule_runtime.plugins_registry import ...` in adapter_base.py. pyproject.toml updated to include plugins_registry* in the packages find directive so setuptools ships it from the wheel root. Co-Authored-By: Claude Opus 4.7 --- scripts/build_runtime_package.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scripts/build_runtime_package.py b/scripts/build_runtime_package.py index 55639213..8d7b5045 100755 --- a/scripts/build_runtime_package.py +++ b/scripts/build_runtime_package.py @@ -268,10 +268,11 @@ molecule-mcp = "molecule_runtime.mcp_cli:main" [tool.setuptools.packages.find] where = ["."] -include = ["molecule_runtime*"] +include = ["molecule_runtime*", "plugins_registry*"] [tool.setuptools.package-data] "molecule_runtime" = ["py.typed"] +"plugins_registry" = ["py.typed"] """ @@ -473,6 +474,18 @@ def main() -> int: py_files = copy_tree_filtered(src, pkg_dir) print(f"[build] copied {len(py_files)} .py files") + # Install plugins_registry/ at the wheel TOP LEVEL so that plugin adapter + # code (workspace-template-*) can use bare `from plugins_registry import ...`. + # The molecule-runtime package (molecule_runtime/) also ships it at + # molecule_runtime/plugins_registry/ (satisfies the rewritten + # `from molecule_runtime.plugins_registry import ...` in adapter_base.py). + # Both copies coexist: they serve different import namespaces. + plugins_src = src / "plugins_registry" + plugins_dst = out / "plugins_registry" + if plugins_src.is_dir(): + shutil.copytree(plugins_src, plugins_dst) + print(f"[build] installed plugins_registry/ at top level (bare-import shim)") + # Ensure top-level package marker exists. workspace/ doesn't have one # (it's not a package in monorepo), but the published artifact must. init = pkg_dir / "__init__.py"