#!/usr/bin/env python3 """Apply persistent non-interactive settings for managed coding clients.""" from __future__ import annotations import json import os from pathlib import Path from typing import Any def configure_claude_state(path: Path) -> None: """Disable Claude's long-session resume chooser without losing state.""" value: dict[str, Any] = {} if path.is_file(): try: loaded = json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): loaded = {} if isinstance(loaded, dict): value = loaded value["bypassPermissionsModeAccepted"] = True value["resumeReturnDismissed"] = True path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(value, indent=2) + "\n", encoding="utf-8") os.chmod(path, 0o600) def configure_claude_settings(path: Path) -> None: """Layer unattended deny rules and a command hook onto Claude settings.""" value: dict[str, Any] = {} if path.is_file(): try: loaded = json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): loaded = {} if isinstance(loaded, dict): value = loaded permissions = value.get("permissions") if not isinstance(permissions, dict): permissions = {} legacy_managed_denies = [ "Bash(kubectl apply *)", "Bash(kubectl delete *)", "Bash(kubectl patch *)", "Bash(kubectl scale *)", "Bash(kubectl exec *)", "Bash(kubectl port-forward *)", "Bash(flux reconcile *)", "Bash(flux suspend *)", "Bash(flux resume *)", "Bash(vault kv *)", ] managed_denies = [ "Bash(git push --force *)", "Bash(git reset --hard *)", "Bash(git clean -f *)", ] existing_denies = permissions.get("deny") if not isinstance(existing_denies, list): existing_denies = [] previous_managed = {*legacy_managed_denies, *managed_denies} existing_denies = [ str(item) for item in existing_denies if str(item) not in previous_managed ] permissions["deny"] = [ *existing_denies, *managed_denies, ] value["permissions"] = permissions hooks = value.get("hooks") if not isinstance(hooks, dict): hooks = {} managed_hook = { "matcher": "Bash", "hooks": [ { "type": "command", "command": "/opt/hermes/.venv/bin/python /opt/coordinator/claude_command_policy.py", "timeout": 10, } ], } existing_hooks = hooks.get("PreToolUse") if not isinstance(existing_hooks, list): existing_hooks = [] existing_hooks = [ item for item in existing_hooks if "claude_command_policy.py" not in json.dumps(item, sort_keys=True) ] hooks["PreToolUse"] = [*existing_hooks, managed_hook] value["hooks"] = hooks path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(value, indent=2) + "\n", encoding="utf-8") os.chmod(path, 0o600) def main() -> None: """Configure provider clients under the persistent Hermes home.""" home = Path(os.environ.get("CLAUDE_CONFIG_DIR", "/opt/data/home/.claude")) configure_claude_state(home / ".claude.json") configure_claude_settings(home / "settings.json") if __name__ == "__main__": main()