@@ -294,24 +294,60 @@ class LoaderApp(App): |
| 294 | self._pending_confirmation = loop.create_future() | 294 | self._pending_confirmation = loop.create_future() |
| 295 | self._pending_command = details | 295 | self._pending_command = details |
| 296 | | 296 | |
| 297 | - # Show the approval bar | 297 | + # Show the approval bar - must use call_from_thread since we're in worker |
| 298 | approval_bar = self.query_one("#approval-bar", ApprovalBar) | 298 | approval_bar = self.query_one("#approval-bar", ApprovalBar) |
| 299 | - self.call_later(lambda: approval_bar.show_approval(tool_name, message, details)) | | |
| 300 | | 299 | |
| 301 | - # Wait for user response | 300 | + def show_bar(): |
| | 301 | + try: |
| | 302 | + approval_bar.show_approval(tool_name, message, details) |
| | 303 | + # Debug log |
| | 304 | + with open("/tmp/loader_debug.log", "a") as f: |
| | 305 | + f.write(f"[approval] Bar shown, waiting for user input\n") |
| | 306 | + except Exception as e: |
| | 307 | + with open("/tmp/loader_debug.log", "a") as f: |
| | 308 | + f.write(f"[approval] Error showing bar: {e}\n") |
| | 309 | + |
| | 310 | + self.call_from_thread(show_bar) |
| | 311 | + |
| | 312 | + # Wait for user response with timeout |
| 302 | try: | 313 | try: |
| 303 | - return await self._pending_confirmation | 314 | + result = await asyncio.wait_for(self._pending_confirmation, timeout=300.0) |
| | 315 | + try: |
| | 316 | + with open("/tmp/loader_debug.log", "a") as f: |
| | 317 | + f.write(f"[approval] Got result: {result}\n") |
| | 318 | + except Exception: |
| | 319 | + pass |
| | 320 | + return result |
| | 321 | + except asyncio.TimeoutError: |
| | 322 | + try: |
| | 323 | + with open("/tmp/loader_debug.log", "a") as f: |
| | 324 | + f.write(f"[approval] Timeout waiting for user\n") |
| | 325 | + except Exception: |
| | 326 | + pass |
| | 327 | + return False |
| 304 | finally: | 328 | finally: |
| 305 | self._pending_confirmation = None | 329 | self._pending_confirmation = None |
| 306 | self._pending_command = "" | 330 | self._pending_command = "" |
| | 331 | + # Hide the bar |
| | 332 | + self.call_from_thread(approval_bar.hide_approval) |
| 307 | | 333 | |
| 308 | def on_approval_bar_approved(self, event: ApprovalBar.Approved) -> None: | 334 | def on_approval_bar_approved(self, event: ApprovalBar.Approved) -> None: |
| 309 | """Handle approval from the bar.""" | 335 | """Handle approval from the bar.""" |
| | 336 | + try: |
| | 337 | + with open("/tmp/loader_debug.log", "a") as f: |
| | 338 | + f.write(f"[approval] Approved handler called\n") |
| | 339 | + except Exception: |
| | 340 | + pass |
| 310 | if self._pending_confirmation and not self._pending_confirmation.done(): | 341 | if self._pending_confirmation and not self._pending_confirmation.done(): |
| 311 | self._pending_confirmation.set_result(True) | 342 | self._pending_confirmation.set_result(True) |
| 312 | | 343 | |
| 313 | def on_approval_bar_rejected(self, event: ApprovalBar.Rejected) -> None: | 344 | def on_approval_bar_rejected(self, event: ApprovalBar.Rejected) -> None: |
| 314 | """Handle rejection from the bar.""" | 345 | """Handle rejection from the bar.""" |
| | 346 | + try: |
| | 347 | + with open("/tmp/loader_debug.log", "a") as f: |
| | 348 | + f.write(f"[approval] Rejected handler called\n") |
| | 349 | + except Exception: |
| | 350 | + pass |
| 315 | if self._pending_confirmation and not self._pending_confirmation.done(): | 351 | if self._pending_confirmation and not self._pending_confirmation.done(): |
| 316 | self._pending_confirmation.set_result(False) | 352 | self._pending_confirmation.set_result(False) |
| 317 | # Refocus input | 353 | # Refocus input |
@@ -319,6 +355,11 @@ class LoaderApp(App): |
| 319 | | 355 | |
| 320 | def on_approval_bar_edit_requested(self, event: ApprovalBar.EditRequested) -> None: | 356 | def on_approval_bar_edit_requested(self, event: ApprovalBar.EditRequested) -> None: |
| 321 | """Handle edit request - put command in input for editing.""" | 357 | """Handle edit request - put command in input for editing.""" |
| | 358 | + try: |
| | 359 | + with open("/tmp/loader_debug.log", "a") as f: |
| | 360 | + f.write(f"[approval] Edit handler called\n") |
| | 361 | + except Exception: |
| | 362 | + pass |
| 322 | if self._pending_confirmation and not self._pending_confirmation.done(): | 363 | if self._pending_confirmation and not self._pending_confirmation.done(): |
| 323 | self._pending_confirmation.set_result(False) | 364 | self._pending_confirmation.set_result(False) |
| 324 | # Put the command in the input field for editing | 365 | # Put the command in the input field for editing |