diff --git a/src/api_hook_client.py b/src/api_hook_client.py index 3f504a5..f77c170 100644 --- a/src/api_hook_client.py +++ b/src/api_hook_client.py @@ -267,3 +267,7 @@ class ApiHookClient: """Mutates the MMA DAG (Directed Acyclic Graph) structure.""" return self._make_request('POST', '/api/mma/dag/mutate', data=data) or {} + def approve_mma_ticket(self, ticket_id: str) -> dict: + """Manually approves a specific ticket for execution in Step Mode.""" + return self._make_request('POST', '/api/mma/ticket/approve', data={"ticket_id": ticket_id}) or {} + diff --git a/src/api_hooks.py b/src/api_hooks.py index ad52460..918dcf3 100644 --- a/src/api_hooks.py +++ b/src/api_hooks.py @@ -605,7 +605,7 @@ class HookHandler(BaseHTTPRequestHandler): elif self.path == "/api/mma/dag/mutate": def mutate_dag(): try: - func = _get_app_attr(app, "_mutate_dag") + func = _get_app_attr(app, "mutate_dag") if func: func(data) except Exception as e: sys.stderr.write(f"[DEBUG] Hook API mutate_dag error: {e}\n") @@ -618,6 +618,23 @@ class HookHandler(BaseHTTPRequestHandler): self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(json.dumps({"status": "queued"}).encode("utf-8")) + elif self.path == "/api/mma/ticket/approve": + ticket_id = data.get("ticket_id") + def approve_ticket(): + try: + func = _get_app_attr(app, "approve_ticket") + if func: func(ticket_id) + except Exception as e: + sys.stderr.write(f"[DEBUG] Hook API approve_ticket error: {e}\n") + sys.stderr.flush() + lock = _get_app_attr(app, "_pending_gui_tasks_lock") + tasks = _get_app_attr(app, "_pending_gui_tasks") + if lock and tasks is not None: + with lock: tasks.append({"action": "custom_callback", "callback": approve_ticket}) + self.send_response(200) + self.send_header("Content-Type", "application/json") + self.end_headers() + self.wfile.write(json.dumps({"status": "queued"}).encode("utf-8")) else: self.send_response(404) self.end_headers() diff --git a/src/app_controller.py b/src/app_controller.py index 061d5fc..c220f97 100644 --- a/src/app_controller.py +++ b/src/app_controller.py @@ -2780,6 +2780,18 @@ class AppController: self.files.append(item) self._refresh_from_project() + def approve_ticket(self, ticket_id: str) -> None: + """Manually approves a ticket for execution.""" + if self.engine and self.engine.engine: + self.engine.engine.approve_task(ticket_id) + else: + # Fallback if engine not running + for t in self.active_tickets: + if t.get('id') == ticket_id: + t['status'] = 'in_progress' + break + self._push_mma_state_update() + def mutate_dag(self, data: dict) -> None: """Modifies task dependencies.""" ticket_id = data.get("ticket_id") diff --git a/src/gui_2.py b/src/gui_2.py index 533d4c8..e70959a 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -3450,7 +3450,7 @@ def hello(): def bulk_execute(self) -> None: for tid in self.ui_selected_tickets: t = next((t for t in self.active_tickets if str(t.get('id', '')) == tid), None) - if t: t['status'] = 'ready' + if t: t['status'] = 'in_progress' self._push_mma_state_update() def bulk_skip(self) -> None: