feat(workspace): implement layout capture/restore and controller integration
This commit is contained in:
+19
-1
@@ -6,6 +6,7 @@ import os
|
||||
import re
|
||||
from typing import Any, List, Dict, Optional, Callable
|
||||
from pathlib import Path
|
||||
from src import workspace_manager
|
||||
import json
|
||||
import uuid
|
||||
import tomli_w
|
||||
@@ -635,7 +636,9 @@ class AppController:
|
||||
'_cb_save_tool_preset': self._cb_save_tool_preset,
|
||||
'_cb_delete_tool_preset': self._cb_delete_tool_preset,
|
||||
'_switch_project': self._switch_project,
|
||||
'_refresh_from_project': self._refresh_from_project
|
||||
'_refresh_from_project': self._refresh_from_project,
|
||||
'save_workspace_profile': self._cb_save_workspace_profile,
|
||||
'load_workspace_profile': self._cb_load_workspace_profile,
|
||||
}
|
||||
|
||||
def _update_gcli_adapter(self, path: str) -> None:
|
||||
@@ -1038,6 +1041,8 @@ class AppController:
|
||||
self.project_paths = list(projects_cfg.get("paths", []))
|
||||
self.active_project_path = projects_cfg.get("active", "")
|
||||
self._load_active_project()
|
||||
self.workspace_manager = workspace_manager.WorkspaceManager(project_root=Path(self.active_project_path).parent if self.active_project_path else None)
|
||||
self.workspace_profiles = self.workspace_manager.load_all_profiles()
|
||||
# Deserialize FileItems in files.paths
|
||||
raw_paths = self.project.get("files", {}).get("paths", [])
|
||||
self.files = []
|
||||
@@ -2250,6 +2255,19 @@ class AppController:
|
||||
if self.rag_config and self.rag_config.enabled:
|
||||
self._rebuild_rag_index()
|
||||
|
||||
def _cb_save_workspace_profile(self, name: str, scope: str = 'project') -> None:
|
||||
if not hasattr(self, '_app') or not self._app:
|
||||
return
|
||||
profile = self._app._capture_workspace_profile(name)
|
||||
self.workspace_manager.save_profile(profile, scope=scope)
|
||||
self.workspace_profiles = self.workspace_manager.load_all_profiles()
|
||||
|
||||
def _cb_load_workspace_profile(self, name: str) -> None:
|
||||
if name in self.workspace_profiles:
|
||||
profile = self.workspace_profiles[name]
|
||||
if hasattr(self, '_app') and self._app:
|
||||
self._app._apply_workspace_profile(profile)
|
||||
|
||||
def _apply_preset(self, name: str, scope: str) -> None:
|
||||
print(f"[DEBUG] _apply_preset: name={name}, scope={scope}")
|
||||
if name == "None":
|
||||
|
||||
@@ -25,6 +25,7 @@ from src import log_registry
|
||||
from src import log_pruner
|
||||
from src import models
|
||||
from src import app_controller
|
||||
from src import workspace_manager
|
||||
from src import mcp_client
|
||||
from src import aggregate
|
||||
from src import markdown_helper
|
||||
@@ -103,6 +104,7 @@ class App:
|
||||
def __init__(self) -> None:
|
||||
# Initialize controller and delegate state
|
||||
self.controller = app_controller.AppController()
|
||||
self.controller._app = self
|
||||
from src import history
|
||||
self.history = history.HistoryManager(max_capacity=100)
|
||||
self._last_ui_snapshot: Optional[history.UISnapshot] = None
|
||||
@@ -115,6 +117,8 @@ class App:
|
||||
if not hasattr(self.controller, 'PROVIDERS'):
|
||||
self.controller.PROVIDERS = PROVIDERS
|
||||
self.controller.init_state()
|
||||
self.workspace_manager = workspace_manager.WorkspaceManager(project_root=self.active_project_root)
|
||||
self.workspace_profiles = self.workspace_manager.load_all_profiles()
|
||||
self.show_windows.setdefault("Diagnostics", False)
|
||||
self.controller.start_services(self)
|
||||
self.controller._predefined_callbacks['_render_text_viewer'] = self._render_text_viewer
|
||||
@@ -346,6 +350,35 @@ class App:
|
||||
finally:
|
||||
self._is_applying_snapshot = False
|
||||
|
||||
def _capture_workspace_profile(self, name: str) -> models.WorkspaceProfile:
|
||||
ini = imgui.save_ini_settings_to_memory()
|
||||
panel_states = {
|
||||
"ui_separate_message_panel": getattr(self, "ui_separate_message_panel", False),
|
||||
"ui_separate_response_panel": getattr(self, "ui_separate_response_panel", False),
|
||||
"ui_separate_tool_calls_panel": getattr(self, "ui_separate_tool_calls_panel", False),
|
||||
"ui_separate_task_dag": getattr(self, "ui_separate_task_dag", False),
|
||||
"ui_separate_usage_analytics": getattr(self, "ui_separate_usage_analytics", False),
|
||||
"ui_separate_tier1": getattr(self, "ui_separate_tier1", False),
|
||||
"ui_separate_tier2": getattr(self, "ui_separate_tier2", False),
|
||||
"ui_separate_tier3": getattr(self, "ui_separate_tier3", False),
|
||||
"ui_separate_tier4": getattr(self, "ui_separate_tier4", False),
|
||||
"ui_separate_external_tools": getattr(self, "ui_separate_external_tools", False),
|
||||
"ui_discussion_split_h": getattr(self, "ui_discussion_split_h", 300.0),
|
||||
}
|
||||
return models.WorkspaceProfile(
|
||||
name=name,
|
||||
ini_content=ini,
|
||||
show_windows=copy.deepcopy(self.show_windows),
|
||||
panel_states=panel_states
|
||||
)
|
||||
|
||||
def _apply_workspace_profile(self, profile: models.WorkspaceProfile):
|
||||
imgui.load_ini_settings_from_memory(profile.ini_content)
|
||||
self.show_windows.update(profile.show_windows)
|
||||
for k, v in profile.panel_states.items():
|
||||
if hasattr(self, k):
|
||||
setattr(self, k, v)
|
||||
|
||||
def _handle_undo(self) -> None:
|
||||
sys.stderr.write(f"[DEBUG History] _handle_undo called. can_undo={self.history.can_undo}\n")
|
||||
sys.stderr.flush()
|
||||
|
||||
Reference in New Issue
Block a user