import sys import json import logging import os # Add project root to sys.path so we can import api_hook_client sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) try: from api_hook_client import ApiHookClient except ImportError: # Fallback for if we are running from root or other locations sys.path.append(os.path.abspath(os.path.dirname(__file__))) from api_hook_client import ApiHookClient def main(): # Setup basic logging to stderr so it doesn't interfere with stdout JSON logging.basicConfig(level=logging.ERROR, stream=sys.stderr) try: # 1. Read JSON from sys.stdin input_data = sys.stdin.read() if not input_data: return hook_input = json.loads(input_data) # 2. Extract 'tool_name' and 'tool_input' tool_name = hook_input.get('tool_name') tool_args = hook_input.get('tool_input', {}) # 3. Check context — if not running via Manual Slop, we pass through (allow) # This prevents the hook from affecting normal CLI usage. hook_context = os.environ.get("GEMINI_CLI_HOOK_CONTEXT") if hook_context != "manual_slop": print(json.dumps({ "decision": "allow", "reason": "Non-programmatic usage (GEMINI_CLI_HOOK_CONTEXT not set)." })) return # 4. Use 'ApiHookClient' (assuming GUI is on http://127.0.0.1:8999) client = ApiHookClient(base_url="http://127.0.0.1:8999") try: # 5. Request confirmation # This is a blocking call that waits for the user in the GUI response = client.request_confirmation(tool_name, tool_args) if response and response.get('approved') is True: # 6. Print 'allow' decision print(json.dumps({"decision": "allow"})) else: # 7. Print 'deny' decision print(json.dumps({ "decision": "deny", "reason": "User rejected tool execution in GUI." })) except Exception as e: # 8. Handle cases where hook server is not reachable # If we ARE in manual_slop context but can't reach the server, we should DENY # because the user expects to be in control. print(json.dumps({ "decision": "deny", "reason": f"Manual Slop hook server unreachable: {str(e)}" })) except Exception as e: # Fallback for unexpected parsing errors print(json.dumps({ "decision": "deny", "reason": f"Internal bridge error: {str(e)}" })) if __name__ == "__main__": main()