diff --git a/augment/hooks/setup.py b/augment/hooks/setup.py index 851647de..027fb56f 100644 --- a/augment/hooks/setup.py +++ b/augment/hooks/setup.py @@ -644,7 +644,7 @@ def _clear_path(path: Path, label: str) -> str: return "failed" -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" print("=" * 60) print("Augment Code Hooks - Clearing Setup") @@ -692,6 +692,8 @@ def clear_setup() -> None: print("Clear Complete!") print("=" * 60) + return not any_failed + def get_device_identifier() -> Optional[str]: system = platform.system().lower() @@ -903,8 +905,7 @@ def main(): print("[backfill] Augment backfill is not supported.") if clear_mode: - clear_setup() - return + return clear_setup() if check_enterprise_hooks_conflict(): print("\n❌ Skipped — Augment is managed by your organization (MDM).") @@ -944,14 +945,14 @@ def main(): if not api_key: if not domain: print("❌ Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(domain) cb_response = run_callback_server(auth_url) if cb_response is None: print("❌ Failed to receive callback. Exiting.") - return + return False try: api_key = (cb_response.get("query") or {}).get("api_key") @@ -965,7 +966,7 @@ def main(): print(f"❌ Setup failed: {safe_error}") else: print("❌ No API key received. Exiting.") - return + return False debug_print("API key received from callback") @@ -973,7 +974,7 @@ def main(): success, message = set_env_var("UNBOUND_AUGMENT_API_KEY", api_key) if not success: print(f"❌ Failed to set environment variable: {message}") - return + return False debug_print("UNBOUND_AUGMENT_API_KEY set successfully") _install_state = detect_install_state() @@ -984,13 +985,13 @@ def main(): debug_print("Setting up hooks...") if not setup_hooks(gateway_url=gateway_url): print("❌ Failed to setup hooks") - return + return False debug_print("Hooks downloaded successfully") debug_print("Configuring Augment settings...") if not configure_augment_settings(): print("❌ Failed to configure Augment settings") - return + return False debug_print("Augment settings configured successfully") print("✅ API key verified and added") @@ -1003,12 +1004,16 @@ def main(): if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True + if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\n⚠️ Setup cancelled.") + sys.exit(1) except Exception as e: print(f"\n❌ Error: {e}") - exit(1) + sys.exit(1) + sys.exit(0 if ok else 1) diff --git a/claude-code/gateway/setup.py b/claude-code/gateway/setup.py index 33b56f60..32ffa691 100644 --- a/claude-code/gateway/setup.py +++ b/claude-code/gateway/setup.py @@ -4,6 +4,7 @@ """ import os +import sys import platform import subprocess import urllib.request @@ -143,12 +144,12 @@ def set_env_var_on_unix(var_name: str, value: str) -> bool: debug_print(f"Writing to shell file: {rc_file}") export_line = f'export {var_name}="{value}"' - was_added = append_to_file(rc_file, export_line) - - if was_added: - return True - else: - return True + append_to_file(rc_file, export_line) + + try: + return any(line.strip() == export_line for line in rc_file.read_text(encoding="utf-8").splitlines()) + except Exception: + return False def set_env_var(var_name: str, value: str) -> Tuple[bool, str]: @@ -293,7 +294,7 @@ def remove_hooks_unbound_script() -> None: debug_print(f"Failed to remove {script_path}: {e}") -def setup_claude_key_helper() -> None: +def setup_claude_key_helper() -> bool: """ Create ~/.claude/anthropic_key.sh that echoes UNBOUND_API_KEY and update ~/.claude/settings.json with apiKeyHelper pointing to that script. @@ -329,8 +330,10 @@ def setup_claude_key_helper() -> None: settings["apiKeyHelper"] = "~/.claude/anthropic_key.sh" settings_path.write_text(json.dumps(settings, indent=2), encoding="utf-8") + return True except Exception as e: - print(f"⚠️ Failed to configure Claude Code key helper: {e}") + print(f"❌ Failed to configure Claude Code key helper: {e}") + return False def run_one_shot_callback_server(frontend_url: str) -> Optional[Dict[str, any]]: @@ -448,7 +451,7 @@ def remove_api_key_helper_setting() -> str: return "failed" -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" print("=" * 60) print("Claude Code - Clearing Setup") @@ -487,6 +490,8 @@ def clear_setup() -> None: print("Clear Complete!") print("=" * 60) + return not any_failed + def get_device_identifier() -> Optional[str]: system = platform.system().lower() @@ -675,8 +680,7 @@ def main(): debug_print("Debug mode enabled") if args.clear: - clear_setup() - return + return clear_setup() if check_enterprise_hooks_conflict(): print("\n❌ Skipped — Claude Code is managed by your organization (MDM).") @@ -704,13 +708,13 @@ def main(): if not api_key: if not args.domain: print("\n❌ Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(args.domain) cb_response = run_one_shot_callback_server(auth_url) if cb_response is None: print("\n❌ Failed to receive callback response. Exiting.") - return + return False try: api_key = (cb_response.get("query") or {}).get("api_key") @@ -719,7 +723,7 @@ def main(): if not api_key: print("\n❌ No api_key found in callback. Exiting.") - return + return False print("API Key Verified ✅") debug_print("API key verification successful") @@ -728,11 +732,14 @@ def main(): success, message = set_env_var("UNBOUND_API_KEY", api_key) if not success: print(f"❌ Failed to configure UNBOUND_API_KEY: {message}") - return + return False debug_print("UNBOUND_API_KEY set successfully") debug_print("Setting ANTHROPIC_BASE_URL environment variable...") success, message = set_env_var("ANTHROPIC_BASE_URL", args.gateway_url) + if not success: + print(f"❌ Failed to configure ANTHROPIC_BASE_URL: {message}") + return False debug_print("ANTHROPIC_BASE_URL set successfully") _install_state = detect_install_state() @@ -742,7 +749,8 @@ def main(): # Configure Claude Code helper files debug_print("Setting up Claude key helper...") - setup_claude_key_helper() + if not setup_claude_key_helper(): + return False debug_print("Claude key helper configured") # Final instructions @@ -756,11 +764,15 @@ def main(): if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True + if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\n⚠️ Setup cancelled by user.") + sys.exit(1) except Exception as e: print(f"\n❌ An error occurred: {e}") - exit(1) + sys.exit(1) + sys.exit(0 if ok else 1) diff --git a/claude-code/hooks/setup.py b/claude-code/hooks/setup.py index a3bce638..bfe5d75d 100644 --- a/claude-code/hooks/setup.py +++ b/claude-code/hooks/setup.py @@ -612,7 +612,7 @@ def _clear_path(path: Path, label: str) -> str: return "failed" -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" print("=" * 60) print("Claude Code Hooks - Clearing Setup") @@ -659,6 +659,7 @@ def clear_setup() -> None: print("\n" + "=" * 60) print("Clear Complete!") print("=" * 60) + return not any_failed def get_device_identifier() -> Optional[str]: @@ -1197,8 +1198,7 @@ def main(): debug_print("Debug mode enabled") if clear_mode: - clear_setup() - return + return clear_setup() if check_enterprise_hooks_conflict(): print("\n❌ Skipped — Claude Code is managed by your organization (MDM).") @@ -1238,14 +1238,14 @@ def main(): if not api_key: if not domain: print("❌ Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(domain) cb_response = run_callback_server(auth_url) if cb_response is None: print("❌ Failed to receive callback. Exiting.") - return + return False try: api_key = (cb_response.get("query") or {}).get("api_key") @@ -1259,7 +1259,7 @@ def main(): print(f"❌ Setup failed: {safe_error}") else: print("❌ No API key received. Exiting.") - return + return False debug_print("API key received from callback") @@ -1275,7 +1275,7 @@ def main(): success, message = set_env_var("UNBOUND_CLAUDE_API_KEY", api_key) if not success: print(f"❌ Failed to set environment variable: {message}") - return + return False debug_print("UNBOUND_CLAUDE_API_KEY set successfully") _install_state = detect_install_state() @@ -1286,13 +1286,13 @@ def main(): debug_print("Setting up hooks...") if not setup_hooks(gateway_url=gateway_url): print("❌ Failed to setup hooks") - return + return False debug_print("Hooks downloaded successfully") debug_print("Configuring Claude settings...") if not configure_claude_settings(): print("❌ Failed to configure Claude settings") - return + return False debug_print("Claude settings configured successfully") print("✅ API key verified and added") @@ -1307,13 +1307,16 @@ def main(): rc_path = get_shell_rc_file() if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\n⚠️ Setup cancelled.") + sys.exit(1) except Exception as e: print(f"\n❌ Error: {e}") - exit(1) \ No newline at end of file + sys.exit(1) + sys.exit(0 if ok else 1) \ No newline at end of file diff --git a/codex/gateway/setup.py b/codex/gateway/setup.py index f459fc55..ee0a609e 100644 --- a/codex/gateway/setup.py +++ b/codex/gateway/setup.py @@ -4,6 +4,7 @@ """ import os +import sys import platform import subprocess import urllib.request @@ -143,12 +144,12 @@ def set_env_var_on_unix(var_name: str, value: str) -> bool: debug_print(f"Writing to shell file: {rc_file}") export_line = f'export {var_name}="{value}"' - was_added = append_to_file(rc_file, export_line) - - if was_added: - return True - else: - return True + append_to_file(rc_file, export_line) + + try: + return any(line.strip() == export_line for line in rc_file.read_text(encoding="utf-8").splitlines()) + except Exception: + return False def set_env_var(var_name: str, value: str) -> Tuple[bool, str]: @@ -456,7 +457,7 @@ def remove_codex_config_base_url() -> str: -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" global DEBUG print("=" * 60) @@ -489,6 +490,7 @@ def clear_setup() -> None: print("\n" + "=" * 60) print("Clear Complete!") print("=" * 60) + return not any_failed def remove_hooks_unbound_script() -> None: @@ -728,8 +730,7 @@ def main(): debug_print("Debug mode enabled") if args.clear: - clear_setup() - return + return clear_setup() if check_enterprise_hooks_conflict(): print("\n❌ Skipped — Codex is managed by your organization (MDM).") @@ -743,13 +744,13 @@ def main(): if not api_key: if not args.domain: print("\n❌ Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(args.domain) cb_response = run_one_shot_callback_server(auth_url) if cb_response is None: print("\n❌ Failed to receive callback response. Exiting.") - return + return False try: api_key = (cb_response.get("query") or {}).get("api_key") @@ -758,7 +759,7 @@ def main(): if not api_key: print("\n❌ No api_key found in callback. Exiting.") - return + return False print("API Key Verified ✅") debug_print("API key verification successful") @@ -779,13 +780,13 @@ def main(): success, message = set_env_var("OPENAI_API_KEY", api_key) if not success: print(f"❌ Failed to configure OPENAI_API_KEY: {message}") - return + return False debug_print("OPENAI_API_KEY set successfully") debug_print("Writing openai_base_url to codex config...") if not write_codex_config(f"{args.gateway_url.rstrip('/')}/v1"): print("❌ Failed to configure openai_base_url in codex config") - return + return False debug_print("openai_base_url written to codex config successfully") write_unbound_config(api_key, urls={"base_url": args.backend_url, "gateway_url": args.gateway_url, "frontend_url": normalize_url(args.domain) if args.domain else None}) @@ -800,12 +801,15 @@ def main(): rc_path = get_shell_rc_file() if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\n⚠️ Setup cancelled by user.") + sys.exit(1) except Exception as e: print(f"\n❌ An error occurred: {e}") - exit(1) + sys.exit(1) + sys.exit(0 if ok else 1) diff --git a/codex/hooks/setup.py b/codex/hooks/setup.py index 4f8f4467..6737be0b 100644 --- a/codex/hooks/setup.py +++ b/codex/hooks/setup.py @@ -618,7 +618,7 @@ def _clear_path(path: Path, label: str) -> str: return "failed" -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" print("=" * 60) print("Codex Hooks - Clearing Setup") @@ -672,6 +672,7 @@ def clear_setup() -> None: print("\n" + "=" * 60) print("Clear Complete!") print("=" * 60) + return not any_failed def enable_codex_hooks_feature() -> bool: @@ -1287,8 +1288,7 @@ def main(): debug_print("Debug mode enabled") if clear_mode: - clear_setup() - return + return clear_setup() if check_enterprise_hooks_conflict(): print("\n❌ Skipped — Codex is managed by your organization (MDM).") @@ -1328,14 +1328,14 @@ def main(): if not api_key: if not domain: print("Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(domain) cb_response = run_callback_server(auth_url) if cb_response is None: print("Failed to receive callback. Exiting.") - return + return False try: api_key = (cb_response.get("query") or {}).get("api_key") @@ -1349,7 +1349,7 @@ def main(): print(f"Setup failed: {safe_error}") else: print("No API key received. Exiting.") - return + return False debug_print("API key received from callback") @@ -1363,7 +1363,7 @@ def main(): success, message = set_env_var("UNBOUND_CODEX_API_KEY", api_key) if not success: print(f"Failed to set environment variable: {message}") - return + return False debug_print("UNBOUND_CODEX_API_KEY set successfully") write_unbound_config(api_key, urls={"base_url": backend_url, "gateway_url": gateway_url, "frontend_url": normalize_url(domain) if domain else None}) @@ -1371,17 +1371,19 @@ def main(): debug_print("Setting up hooks...") if not setup_hooks(gateway_url=gateway_url): print("Failed to setup hooks") - return + return False debug_print("Hooks downloaded successfully") debug_print("Configuring Codex hooks...") if not configure_codex_hooks(): print("Failed to configure Codex hooks") - return + return False debug_print("Codex hooks configured successfully") debug_print("Enabling codex_hooks feature flag...") - enable_codex_hooks_feature() + if not enable_codex_hooks_feature(): + print("Failed to enable codex_hooks feature flag") + return False print("API key verified and added") print("Setup complete") @@ -1396,12 +1398,16 @@ def main(): if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True + if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\nSetup cancelled.") + sys.exit(1) except Exception as e: print(f"\nError: {e}") - exit(1) + sys.exit(1) + sys.exit(0 if ok else 1) diff --git a/copilot/hooks/setup.py b/copilot/hooks/setup.py index bccdbc81..f51367c8 100644 --- a/copilot/hooks/setup.py +++ b/copilot/hooks/setup.py @@ -422,7 +422,7 @@ def _clear_path(path: Path, label: str) -> str: return "failed" -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" print("=" * 60) print("Unbound Copilot Hooks - Clearing Setup") @@ -458,6 +458,8 @@ def clear_setup() -> None: print("Clear Complete!") print("=" * 60) + return not any_failed + def get_device_identifier() -> Optional[str]: system = platform.system().lower() @@ -987,8 +989,7 @@ def main(): debug_print("Debug mode enabled") if clear_mode: - clear_setup() - return + return clear_setup() install_macos_certificates() @@ -1024,14 +1025,14 @@ def main(): if not api_key: if not domain: print("\n❌ Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(domain) cb_response = run_callback_server(auth_url) if cb_response is None: print("\n❌ Failed to receive callback. Exiting.") - return + return False try: api_key = (cb_response.get("query") or {}).get("api_key") @@ -1040,7 +1041,7 @@ def main(): if not api_key: print("\n❌ No API key received. Exiting.") - return + return False print("✅ API key received") debug_print("API key received from callback") @@ -1055,7 +1056,7 @@ def main(): success, message = set_env_var("UNBOUND_COPILOT_API_KEY", api_key) if not success: print(f"❌ Failed to set environment variable: {message}") - return + return False print(f"✅ Environment variable set") debug_print("UNBOUND_COPILOT_API_KEY set successfully") @@ -1063,13 +1064,13 @@ def main(): debug_print("Setting up hooks...") if not setup_hooks(gateway_url=gateway_url): print("\n❌ Failed to setup hooks") - return + return False debug_print("Hooks setup complete") debug_print("Configuring Copilot hooks...") if not configure_copilot_hooks(): print("\n❌ Failed to configure Copilot hooks") - return + return False debug_print("Copilot hooks configured") print("\n" + "=" * 60) @@ -1085,12 +1086,16 @@ def main(): if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True + if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\n⚠️ Setup cancelled.") + sys.exit(1) except Exception as e: print(f"\n❌ Error: {e}") - exit(1) + sys.exit(1) + sys.exit(0 if ok else 1) diff --git a/cursor/setup.py b/cursor/setup.py index 0c47fea5..dd230741 100644 --- a/cursor/setup.py +++ b/cursor/setup.py @@ -455,7 +455,7 @@ def _clear_path(path: Path, label: str) -> str: return "failed" -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" print("=" * 60) print("Unbound Cursor Hooks - Clearing Setup") @@ -490,6 +490,7 @@ def clear_setup() -> None: print("\n" + "=" * 60) print("Clear Complete!") print("=" * 60) + return not any_failed def get_device_identifier() -> Optional[str]: @@ -642,8 +643,7 @@ def main(): print("[backfill] Cursor backfill is not supported — no historical transcript data is available on disk.") if clear_mode: - clear_setup() - return + return clear_setup() if check_enterprise_hooks_conflict(): print("\n❌ Skipped — Cursor is managed by your organization (MDM).") @@ -683,14 +683,14 @@ def main(): if not api_key: if not domain: print("\n❌ Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(domain) cb_response = run_callback_server(auth_url) if cb_response is None: print("\n❌ Failed to receive callback. Exiting.") - return + return False try: api_key = (cb_response.get("query") or {}).get("api_key") @@ -699,7 +699,7 @@ def main(): if not api_key: print("\n❌ No API key received. Exiting.") - return + return False print("✅ API key received") debug_print("API key received from callback") @@ -714,7 +714,7 @@ def main(): success, message = set_env_var("UNBOUND_CURSOR_API_KEY", api_key) if not success: print(f"❌ Failed to set environment variable: {message}") - return + return False print(f"✅ Environment variable set") debug_print("UNBOUND_CURSOR_API_KEY set successfully") @@ -722,7 +722,7 @@ def main(): debug_print("Setting up hooks...") if not setup_hooks(gateway_url=gateway_url): print("\n❌ Failed to setup hooks") - return + return False debug_print("Hooks setup complete") print("\n" + "=" * 60) @@ -736,13 +736,16 @@ def main(): rc_path = get_shell_rc_file() if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\n⚠️ Setup cancelled.") + sys.exit(1) except Exception as e: print(f"\n❌ Error: {e}") - exit(1) \ No newline at end of file + sys.exit(1) + sys.exit(0 if ok else 1) \ No newline at end of file diff --git a/gemini-cli/gateway/setup.py b/gemini-cli/gateway/setup.py index c6fa88ff..a7c4935d 100644 --- a/gemini-cli/gateway/setup.py +++ b/gemini-cli/gateway/setup.py @@ -4,6 +4,7 @@ """ import os +import sys import platform import subprocess import urllib.request @@ -143,12 +144,12 @@ def set_env_var_on_unix(var_name: str, value: str) -> bool: debug_print(f"Writing to shell file: {rc_file}") export_line = f'export {var_name}="{value}"' - was_added = append_to_file(rc_file, export_line) - - if was_added: - return True - else: - return True + append_to_file(rc_file, export_line) + + try: + return any(line.strip() == export_line for line in rc_file.read_text(encoding="utf-8").splitlines()) + except Exception: + return False def set_env_var(var_name: str, value: str) -> Tuple[bool, str]: @@ -364,7 +365,7 @@ def write_unbound_config(api_key: str, urls: dict = None) -> bool: -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" print("=" * 60) print("Gemini CLI - Clearing Setup") @@ -390,6 +391,8 @@ def clear_setup() -> None: print("Clear Complete!") print("=" * 60) + return not any_failed + def get_device_identifier() -> Optional[str]: system = platform.system().lower() @@ -548,8 +551,7 @@ def main(): debug_print("Debug mode enabled") if args.clear: - clear_setup() - return + return clear_setup() print("=" * 60) print("Gemini CLI - Environment Setup") @@ -559,13 +561,13 @@ def main(): if not api_key: if not args.domain: print("\n❌ Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(args.domain) cb_response = run_one_shot_callback_server(auth_url) if cb_response is None: print("\n❌ Failed to receive callback response. Exiting.") - return + return False try: api_key = (cb_response.get("query") or {}).get("api_key") @@ -574,7 +576,7 @@ def main(): if not api_key: print("\n❌ No api_key found in callback. Exiting.") - return + return False print("API Key Verified ✅") debug_print("API key verification successful") @@ -583,11 +585,14 @@ def main(): success, message = set_env_var("GEMINI_API_KEY", api_key) if not success: print(f"❌ Failed to configure GEMINI_API_KEY: {message}") - return + return False debug_print("GEMINI_API_KEY set successfully") debug_print("Setting GOOGLE_GEMINI_BASE_URL environment variable...") success, message = set_env_var("GOOGLE_GEMINI_BASE_URL", f"{args.gateway_url.rstrip('/')}/v1") + if not success: + print(f"❌ Failed to configure GOOGLE_GEMINI_BASE_URL: {message}") + return False debug_print("GOOGLE_GEMINI_BASE_URL set successfully") _install_state = detect_install_state() @@ -606,11 +611,15 @@ def main(): if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True + if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\n⚠️ Setup cancelled by user.") + sys.exit(1) except Exception as e: print(f"\n❌ An error occurred: {e}") - exit(1) + sys.exit(1) + sys.exit(0 if ok else 1) diff --git a/openclaw/setup.py b/openclaw/setup.py index 71c4851e..950a56be 100644 --- a/openclaw/setup.py +++ b/openclaw/setup.py @@ -371,7 +371,7 @@ def _report_status(status: str, label: str) -> bool: return False -def clear_setup() -> None: +def clear_setup() -> bool: """Undo all changes made by the setup script.""" print("=" * 60) print("OpenClaw Unbound Plugin - Clearing Setup") @@ -463,6 +463,7 @@ def clear_setup() -> None: print("\n" + "=" * 60) print("Clear Complete!") print("=" * 60) + return not any_failed def notify_setup_complete(api_key: str, tool_type: str, backend_url: str = "https://backend.getunbound.ai"): @@ -495,8 +496,7 @@ def main(): debug_print("Debug mode enabled") if clear_mode: - clear_setup() - return + return clear_setup() install_macos_certificates() @@ -532,14 +532,14 @@ def main(): if not api_key: if not domain: print("❌ Missing required argument: --domain or --api-key") - return + return False auth_url = normalize_url(domain) api_key = run_callback_server(auth_url) if not api_key: print("❌ No API key received. Exiting.") - return + return False debug_print("API key received from callback") @@ -548,13 +548,13 @@ def main(): success, message = set_env_var(ENV_VAR_NAME, api_key) if not success: print(f"❌ Failed to set environment variable: {message}") - return + return False # Configure OpenClaw debug_print("Configuring OpenClaw...") if not configure_openclaw(gateway_url, setup_plugin=setup_plugin, setup_provider=setup_provider, model=model): print("❌ Failed to configure OpenClaw") - return + return False print("✅ API key verified and added") if setup_plugin: @@ -575,12 +575,16 @@ def main(): if rc_path is not None: print(f"\nTo apply changes in your current terminal, run:\n source {rc_path}\n\nOr open a new terminal.") + return True + if __name__ == "__main__": try: - main() + ok = main() except KeyboardInterrupt: print("\n\n⚠️ Setup cancelled.") + sys.exit(1) except Exception as e: print(f"\n❌ Error: {e}") - exit(1) + sys.exit(1) + sys.exit(0 if ok else 1)