← Files ClaraARCHIVED FILE
scripts/bootstrap_python_dependencies.py
3.94 KB · Oct 2, 2026 · 00:29 UTC
#!/usr/bin/env python3
"""Prepare Clara's persistent managed Python runtime for Claude Cowork."""
from __future__ import annotations
import importlib.util
import json
import os
import shlex
import subprocess
import sys
from pathlib import Path
from typing import Callable
__all__ = [
"bootstrap_dependencies",
"dependency_target",
"main",
"plugin_data_dir",
"plugin_root",
"requirements_fingerprint",
"write_pythonpath",
]
Runner = Callable[..., subprocess.CompletedProcess[str]]
DEPENDENCY_DIR_NAME = "python-dependencies"
def _load_runtime():
path = Path(__file__).with_name("managed_python_runtime.py")
spec = importlib.util.spec_from_file_location("clara_bootstrap_runtime", path)
if spec is None or spec.loader is None:
raise RuntimeError(f"Could not load managed Python runtime: {path}")
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
return module
_RUNTIME = _load_runtime()
def plugin_root() -> Path:
"""Return the installed Clara plugin root."""
configured = os.environ.get("CLAUDE_PLUGIN_ROOT") or os.environ.get("PLUGIN_ROOT")
return (
Path(configured).expanduser().resolve()
if configured
else Path(__file__).resolve().parents[1]
)
def plugin_data_dir() -> Path:
"""Return Clara's user-scoped persistent data directory."""
return _RUNTIME.plugin_data_dir(plugin_root())
def requirements_fingerprint(root: Path) -> str:
"""Return the fingerprint for Clara's core requirement graph."""
return _RUNTIME.requirements_fingerprint(_RUNTIME.select_runtime(root))
def dependency_target(root: Path, data_dir: Path) -> Path:
"""Return Clara's core managed dependency target."""
return _RUNTIME.dependency_target(_RUNTIME.select_runtime(root), data_dir)
def write_pythonpath(target: Path, env_file: Path | None) -> None:
"""Expose the virtual environment to subsequent Claude shell commands."""
if env_file is None:
return
env_file.parent.mkdir(parents=True, exist_ok=True)
marker = "# Clara Python dependencies"
existing = env_file.read_text(encoding="utf-8") if env_file.exists() else ""
if marker in existing:
return
quoted_target = shlex.quote(str(target))
quoted_scripts = shlex.quote(str(_RUNTIME.runtime_python(target).parent))
with env_file.open("a", encoding="utf-8") as handle:
if existing and not existing.endswith("\n"):
handle.write("\n")
handle.write(
f"{marker}\n"
f"export VIRTUAL_ENV={quoted_target}\n"
f"export PATH={quoted_scripts}${{PATH:+:${{PATH}}}}\n"
)
def bootstrap_dependencies(
root: Path,
data_dir: Path,
env_file: Path | None,
*,
runner: Runner = subprocess.run,
) -> tuple[bool, str]:
"""Install or reuse Clara's managed core target and expose it to Cowork."""
ready, target, detail = _RUNTIME.ensure_runtime(
root,
data_dir=data_dir,
runner=runner,
)
if ready:
write_pythonpath(target, env_file)
return ready, detail
def main() -> int:
"""Run the fail-open SessionStart dependency bootstrap."""
root = plugin_root()
data_dir = plugin_data_dir()
env_file_value = os.environ.get("CLAUDE_ENV_FILE")
env_file = Path(env_file_value).resolve() if env_file_value else None
try:
ready, detail = bootstrap_dependencies(root, data_dir, env_file)
except (OSError, subprocess.SubprocessError, ValueError) as error:
ready, detail = False, str(error)
if not ready:
message = (
"Clara could not prepare its managed Python runtime in the user "
f"sandbox: {detail}. File-based work remains available, but "
"Python-backed workflows must rerun the dependency bootstrap."
)
print(json.dumps({"systemMessage": message}))
return 0
if __name__ == "__main__":
raise SystemExit(main())
SHA-256: 7aec99fe4f0cc62d7d658468f656bfb2a1a925199cfcc5b8fb14a4ff0e5e3a2b