cruft cleanup part 3
This commit is contained in:
+2
-16
@@ -87,10 +87,7 @@ def resolve_paths(base_dir: Path, entry: str) -> list[Path]:
|
||||
return sorted(filtered)
|
||||
|
||||
def group_files_by_dir(files: list[Any]) -> dict[str, list[Any]]:
|
||||
"""
|
||||
Groups FileItem objects by their relative directory path.
|
||||
[C: src/gui_2.py:App._render_context_files_table, tests/test_context_composition_phase3.py:test_group_files_by_dir]
|
||||
"""
|
||||
"""Groups FileItem objects by their relative directory path."""
|
||||
grouped = {}
|
||||
for f in files:
|
||||
path_str = f.path if hasattr(f, 'path') else str(f)
|
||||
@@ -105,10 +102,7 @@ def group_files_by_dir(files: list[Any]) -> dict[str, list[Any]]:
|
||||
return grouped
|
||||
|
||||
def compute_file_stats(abs_path: str) -> Result[dict[str, int]]:
|
||||
"""
|
||||
Computes lines and basic AST stats for a file.
|
||||
[C: src/gui_2.py:App._stats_worker, tests/test_context_composition_phase3.py:test_compute_file_stats]
|
||||
"""
|
||||
"""Computes lines and basic AST stats for a file."""
|
||||
stats = {"lines": 0, "ast_elements": 0}
|
||||
errors: list[ErrorInfo] = []
|
||||
try:
|
||||
@@ -173,7 +167,6 @@ def build_file_items(base_dir: Path, files: list[str | Metadata]) -> list[Metada
|
||||
auto_aggregate : bool
|
||||
force_full : bool
|
||||
view_mode : str (summary, full, skeleton, outline, none)
|
||||
[C: src/app_controller.py:AppController._bg_task, src/orchestrator_pm.py:module, tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_aggregate_flags.py:test_force_full, tests/test_context_composition_phase6.py:test_view_mode_custom, tests/test_context_composition_phase6.py:test_view_mode_custom_empty_default_to_summary, tests/test_context_composition_phase6.py:test_view_mode_default_summary, tests/test_context_composition_phase6.py:test_view_mode_full, tests/test_context_composition_phase6.py:test_view_mode_none, tests/test_context_composition_phase6.py:test_view_mode_outline, tests/test_context_composition_phase6.py:test_view_mode_skeleton, tests/test_context_composition_phase6.py:test_view_mode_summary, tests/test_tiered_context.py:test_build_file_items_with_tiers, tests/test_tiered_context.py:test_build_files_section_with_dicts]
|
||||
"""
|
||||
with get_monitor().scope("build_file_items"):
|
||||
items: list[Metadata] = []
|
||||
@@ -376,7 +369,6 @@ def build_tier3_context(file_items: list[Metadata], screenshot_base_dir: Path, s
|
||||
"""
|
||||
Tier 3 Context: Execution/Worker.
|
||||
Full content for focus_files and files with tier=3, summaries/skeletons for others.
|
||||
[C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_aggregate_flags.py:test_force_full, tests/test_ast_masking_core.py:test_ast_masking_gencpp_samples, tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_tiered_context.py:test_build_tier3_context_ast_skeleton, tests/test_tiered_context.py:test_build_tier3_context_exists, tests/test_tiered_context.py:test_tiered_context_by_tier_field]
|
||||
"""
|
||||
with get_monitor().scope("build_tier3_context"):
|
||||
focus_set = set(focus_files)
|
||||
@@ -470,9 +462,6 @@ def build_markdown(base_dir: Path, files: list[str | Metadata], screenshot_base_
|
||||
return build_markdown_from_items(file_items, screenshot_base_dir, screenshots, history, summary_only=summary_only, aggregation_strategy='auto', execution_mode=execution_mode, base_dir=base_dir)
|
||||
|
||||
def run(config: Metadata, aggregation_strategy: str = "auto") -> tuple[str, Path, list[Metadata]]:
|
||||
"""
|
||||
[C: simulation/sim_base.py:run_sim, src/ai_client.py:_send_anthropic, src/ai_client.py:_send_deepseek, src/ai_client.py:_send_gemini, src/ai_client.py:_send_gemini_cli, src/ai_client.py:_send_minimax, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._start_track_logic, src/external_editor.py:_find_vscode_in_registry, src/gui_2.py:App._render_snapshot_tab, src/gui_2.py:App.run, src/gui_2.py:main, src/mcp_client.py:get_git_diff, src/project_manager.py:get_git_commit, src/rag_engine.py:RAGEngine._search_mcp, src/shell_runner.py:run_powershell, tests/conftest.py:kill_process_tree, tests/conftest.py:live_gui, tests/test_conductor_abort_event.py:test_conductor_abort_event_populated, tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_conductor_engine_v2.py:test_conductor_engine_run_executes_tickets_in_order, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_extended_sims.py:test_context_sim_live, tests/test_extended_sims.py:test_execution_sim_live, tests/test_extended_sims.py:test_tools_sim_live, tests/test_external_editor_gui.py:get_vscode_processes, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_custom_window.py:test_app_window_is_borderless, tests/test_headless_simulation.py:module, tests/test_headless_verification.py:test_headless_verification_error_and_qa_interceptor, tests/test_headless_verification.py:test_headless_verification_full_run, tests/test_mock_gemini_cli.py:run_mock, tests/test_orchestration_logic.py:test_conductor_engine_run, tests/test_parallel_execution.py:test_conductor_engine_pool_integration, tests/test_sim_ai_settings.py:test_ai_settings_simulation_run, tests/test_sim_context.py:test_context_simulation_run, tests/test_sim_execution.py:test_execution_simulation_run, tests/test_sim_tools.py:test_tools_simulation_run]
|
||||
"""
|
||||
namespace = config.get("project", {}).get("name")
|
||||
if not namespace: namespace = config.get("output", {}).get("namespace", "project")
|
||||
output_dir = Path(config["output"]["output_dir"])
|
||||
@@ -504,9 +493,6 @@ def run(config: Metadata, aggregation_strategy: str = "auto") -> tuple[str, Path
|
||||
|
||||
def main() -> None:
|
||||
# Load global config to find active project
|
||||
"""
|
||||
[C: simulation/live_walkthrough.py:module, simulation/ping_pong.py:module, src/ai_server.py:module, src/api_hooks.py:WebSocketServer._run_loop, src/gui_2.py:module, tests/mock_concurrent_mma.py:module, tests/mock_gemini_cli.py:module, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_allow_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_deny_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_unreachable_hook_server, tests/test_cli_tool_bridge.py:module, tests/test_cli_tool_bridge_mapping.py:TestCliToolBridgeMapping.test_mapping_from_api_format, tests/test_cli_tool_bridge_mapping.py:module, tests/test_discussion_takes.py:module, tests/test_external_editor_gui.py:module, tests/test_headless_service.py:TestHeadlessStartup.test_headless_flag_triggers_run, tests/test_headless_service.py:TestHeadlessStartup.test_normal_startup_calls_app_run, tests/test_mma_skeleton.py:module, tests/test_orchestrator_pm.py:module, tests/test_orchestrator_pm_history.py:module, tests/test_presets.py:module, tests/test_project_serialization.py:module, tests/test_run_worker_lifecycle_abort.py:module, tests/test_symbol_lookup.py:module, tests/test_system_prompt_exposure.py:module, tests/test_theme_nerv_fx.py:module]
|
||||
"""
|
||||
config_path = get_config_path()
|
||||
if not config_path.exists():
|
||||
|
||||
|
||||
@@ -776,9 +776,6 @@ def _build_anthropic_tools() -> list[ToolDefinition]:
|
||||
_CACHED_ANTHROPIC_TOOLS: Optional[FileItems] = None
|
||||
|
||||
def _get_anthropic_tools() -> list[Metadata]:
|
||||
"""
|
||||
[C: tests/test_bias_efficacy.py:test_bias_efficacy_prompt_generation, tests/test_bias_efficacy.py:test_bias_parameter_nudging, tests/test_bias_integration.py:test_tool_declaration_biasing_anthropic]
|
||||
"""
|
||||
global _CACHED_ANTHROPIC_TOOLS
|
||||
if _CACHED_ANTHROPIC_TOOLS is None:
|
||||
_CACHED_ANTHROPIC_TOOLS = _build_anthropic_tools()
|
||||
@@ -906,8 +903,6 @@ async def _execute_tool_calls_concurrently(
|
||||
|
||||
Thread Boundaries:
|
||||
Runs in the active asyncio event loop thread.
|
||||
|
||||
[C: tests/test_async_tools.py:test_execute_tool_calls_concurrently_exception_handling, tests/test_async_tools.py:test_execute_tool_calls_concurrently_timing]
|
||||
"""
|
||||
monitor = performance_monitor.get_monitor()
|
||||
if monitor.enabled: monitor.start_component("ai_client._execute_tool_calls_concurrently")
|
||||
@@ -2288,7 +2283,6 @@ def _send_deepseek(md_content: str, user_message: str, base_dir: str,
|
||||
stream_callback: Optional[Callable[[str], None]] = None,
|
||||
patch_callback: Optional[Callable[[str, str], Result[str]]] = None) -> Result[str]:
|
||||
"""
|
||||
[C: src/ai_server.py:_handle_send]
|
||||
Functional Purpose: Sends requests to DeepSeek via requests.post API call, managing history repairs and tools.
|
||||
Parameters & Inputs: md_content, user_message, base_dir, file_items, discussion_history, stream, callbacks.
|
||||
Immediate-Mode DAG / Thread Context: Called by: send; Calls: _ensure_deepseek_client, _repair_deepseek_history, requests.post
|
||||
@@ -3277,9 +3271,6 @@ def _run_tier4_patch_generation_result(error: str, file_context: str) -> Result[
|
||||
|
||||
|
||||
def run_tier4_patch_generation(error: str, file_context: str) -> str:
|
||||
"""
|
||||
[C: src/gui_2.py:App.request_patch_from_tier4, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_calls_ai, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_empty_error, tests/test_tier4_patch_generation.py:test_run_tier4_patch_generation_returns_diff]
|
||||
"""
|
||||
return _run_tier4_patch_generation_result(error, file_context).data
|
||||
|
||||
def _count_gemini_tokens_for_stats_result(md_content: str) -> Result[int]:
|
||||
@@ -3305,9 +3296,6 @@ def _count_gemini_tokens_for_stats_result(md_content: str) -> Result[int]:
|
||||
|
||||
|
||||
def get_token_stats(md_content: str) -> Metadata:
|
||||
"""
|
||||
[C: src/app_controller.py:AppController._refresh_api_metrics]
|
||||
"""
|
||||
global _provider, _gemini_client, _model, _CHARS_PER_TOKEN
|
||||
total_tokens = 0
|
||||
p = str(_provider).lower().strip()
|
||||
@@ -3380,8 +3368,6 @@ def send(
|
||||
Thread Boundaries:
|
||||
Acquires the global _send_lock to synchronize provider calls. Safely called from any worker
|
||||
thread executing background tasks, preventing concurrent thread collisions on shared provider SDK states.
|
||||
|
||||
[C: tests/test_ai_client_result.py:test_send_public_api_returns_result, tests/test_ai_client_result.py:test_send_preserves_errors, tests/test_deprecation_warnings.py:test_send_does_not_emit_deprecation]
|
||||
"""
|
||||
monitor = performance_monitor.get_monitor()
|
||||
if monitor.enabled: monitor.start_component("ai_client.send")
|
||||
@@ -3453,9 +3439,6 @@ def send(
|
||||
return res
|
||||
|
||||
def _add_bleed_derived(d: Metadata, sys_tok: int = 0, tool_tok: int = 0) -> Metadata:
|
||||
"""
|
||||
[C: tests/test_token_viz.py:test_add_bleed_derived_aliases, tests/test_token_viz.py:test_add_bleed_derived_breakdown, tests/test_token_viz.py:test_add_bleed_derived_headroom, tests/test_token_viz.py:test_add_bleed_derived_headroom_clamped_to_zero, tests/test_token_viz.py:test_add_bleed_derived_history_clamped_to_zero, tests/test_token_viz.py:test_add_bleed_derived_would_trim_false, tests/test_token_viz.py:test_add_bleed_derived_would_trim_true, tests/test_token_viz.py:test_would_trim_boundary_exact, tests/test_token_viz.py:test_would_trim_just_above_threshold, tests/test_token_viz.py:test_would_trim_just_below_threshold]
|
||||
"""
|
||||
cur = d.get("current", 0)
|
||||
lim = d.get("limit", 0)
|
||||
d["estimated_prompt_tokens"] = cur
|
||||
@@ -3477,9 +3460,6 @@ if os.environ.get("SLOP_TOOL_PRESET"):
|
||||
#region: Subagent Summarization
|
||||
|
||||
def run_subagent_summarization(file_path: str, content: str, is_code: bool, outline: str) -> str:
|
||||
"""
|
||||
[C: src/summarize.py:summarise_file, tests/test_subagent_summarization.py:test_run_subagent_summarization_anthropic, tests/test_subagent_summarization.py:test_run_subagent_summarization_gemini]
|
||||
"""
|
||||
requests = _require_warmed("requests")
|
||||
genai = _require_warmed("google.genai")
|
||||
types = genai.types
|
||||
|
||||
+13
-221
@@ -90,9 +90,6 @@ class ConfirmDialog:
|
||||
self._approved = False
|
||||
|
||||
def wait(self) -> tuple[bool, str]:
|
||||
"""
|
||||
[C: src/mcp_client.py:StdioMCPServer.stop, src/multi_agent_conductor.py:confirm_execution, src/multi_agent_conductor.py:confirm_spawn, tests/conftest.py:live_gui, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_ai_server.py:test_server_handles_list_models, tests/test_ai_server.py:test_server_handles_unknown_method, tests/test_ai_server.py:test_server_loads_google_genai_quickly, tests/test_ai_server.py:test_server_outputs_ready_marker, tests/test_ai_server.py:test_server_starts_and_exits_cleanly, tests/test_conductor_engine_abort.py:worker, tests/test_parallel_execution.py:test_worker_pool_limit]
|
||||
"""
|
||||
start_time = time.time()
|
||||
with self._condition:
|
||||
while not self._done:
|
||||
@@ -1945,10 +1942,7 @@ class AppController:
|
||||
f.write(data)
|
||||
|
||||
def init_state(self):
|
||||
"""
|
||||
Initializes the application state from configurations.
|
||||
[C: src/gui_2.py:App.__init__, src/gui_2.py:App._save_paths, src/gui_2.py:App._set_external_editor_default, tests/test_app_controller_mcp.py:test_app_controller_mcp_loading, tests/test_app_controller_mcp.py:test_app_controller_mcp_project_override, tests/test_context_composition_decoupled.py:test_do_generate_uses_context_files, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_app_controller_init_state_loads_prompts]
|
||||
"""
|
||||
"""Initializes the application state from configurations."""
|
||||
self.active_tickets = []
|
||||
self.ui_separate_task_dag = False
|
||||
self.ui_separate_usage_analytics = False
|
||||
@@ -2119,9 +2113,6 @@ class AppController:
|
||||
self.event_queue.put('refresh_external_mcps', None)
|
||||
|
||||
async def refresh_external_mcps(self):
|
||||
"""
|
||||
[C: tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call]
|
||||
"""
|
||||
await mcp_client.get_external_mcp_manager().stop_all()
|
||||
# Start servers with auto_start=True
|
||||
for name, cfg in self.mcp_config.mcpServers.items():
|
||||
@@ -2199,9 +2190,6 @@ class AppController:
|
||||
)])
|
||||
|
||||
def cb_load_prior_log(self, path: Optional[str] = None) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_log_management, src/gui_2.py:App.cb_load_prior_log]
|
||||
"""
|
||||
if not path:
|
||||
return
|
||||
|
||||
@@ -2614,7 +2602,8 @@ class AppController:
|
||||
|
||||
def warmup_canaries(self) -> list[dict]:
|
||||
"""
|
||||
Per-module import canary records. Each record carries: canary_id, module, thread_name, thread_id, submit_ts, start_ts, end_ts, elapsed_ms, status, error. Useful for debugging which worker thread loaded which module and how long it took. Returns a defensive copy (caller mutation is safe). [SDM: src/app_controller.py:warmup_canaries].
|
||||
Per-module import canary records. Each record carries: canary_id, module, thread_name, thread_id, submit_ts, start_ts, end_ts, elapsed_ms, status, error.
|
||||
Useful for debugging which worker thread loaded which module and how long it took. Returns a defensive copy (caller mutation is safe). [SDM: src/app_controller.py:warmup_canaries].
|
||||
"""
|
||||
return self._warmup.canaries()
|
||||
|
||||
@@ -2701,7 +2690,6 @@ class AppController:
|
||||
if the io_pool is still processing jobs from a prior test, submitting
|
||||
a new project switch would queue behind them and the switch would
|
||||
not complete promptly.
|
||||
[C: tests/test_live_workflow.py:test_full_live_workflow]
|
||||
"""
|
||||
return getattr(self, "_io_pool_inflight", 0) == 0
|
||||
|
||||
@@ -2717,7 +2705,6 @@ class AppController:
|
||||
def shutdown(self) -> None:
|
||||
"""
|
||||
Stops background threads and cleans up resources.
|
||||
[C: src/gui_2.py:App.run, src/gui_2.py:App.shutdown, tests/conftest.py:app_instance, tests/conftest.py:mock_app]
|
||||
"""
|
||||
from src import ai_client
|
||||
ai_client.cleanup()
|
||||
@@ -2823,7 +2810,6 @@ class AppController:
|
||||
"""
|
||||
Creates and configures the FastAPI application for headless mode.
|
||||
[SDM: src/app_controller.py:AppController.create_api]
|
||||
[C: src/gui_2.py:App.run, tests/test_headless_service.py:TestHeadlessAPI.setUp]
|
||||
"""
|
||||
fastapi = _require_warmed("fastapi")
|
||||
FastAPI = fastapi.FastAPI
|
||||
@@ -2841,21 +2827,12 @@ class AppController:
|
||||
return _api_health(self)
|
||||
@api.get("/api/gui/state", dependencies=[Depends(get_api_key)])
|
||||
def get_gui_state() -> Metadata:
|
||||
"""
|
||||
[C: tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_conductor_api_hook_integration.py:simulate_conductor_phase_completion, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_workflow.py:test_full_live_workflow, tests/test_live_workflow.py:wait_for_value, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tool_management_layout.py:test_tool_management_gettable_fields, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout, tests/test_visual_mma.py:test_visual_mma_components]
|
||||
"""
|
||||
return _api_get_gui_state(self)
|
||||
@api.get("/api/gui/mma_status", dependencies=[Depends(get_api_key)])
|
||||
def get_mma_status() -> Metadata:
|
||||
"""
|
||||
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_live_workflow.py:test_full_live_workflow, tests/test_mma_concurrent_tracks_sim.py:_poll_mma_status, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_step_mode_sim.py:_poll_mma_status, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:_poll]
|
||||
"""
|
||||
return _api_get_mma_status(self)
|
||||
@api.post("/api/gui", dependencies=[Depends(get_api_key)])
|
||||
def post_gui(req: dict) -> dict[str, str]:
|
||||
"""
|
||||
[C: tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_api_hook_client.py:test_post_gui_success, tests/test_gui2_parity.py:test_gui2_custom_callback_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works]
|
||||
"""
|
||||
return _api_post_gui(self, req)
|
||||
@api.get("/api/session", dependencies=[Depends(get_api_key)])
|
||||
def get_api_session() -> Metadata:
|
||||
@@ -2895,18 +2872,12 @@ class AppController:
|
||||
return _api_list_sessions(self)
|
||||
@api.get("/api/v1/sessions/{session_id}", dependencies=[Depends(get_api_key)])
|
||||
def get_session(session_id: str) -> Metadata:
|
||||
"""
|
||||
[C: simulation/ping_pong.py:main, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/sim_tools.py:ToolsSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/test_api_hook_client.py:test_get_session_success, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_live_workflow.py:test_full_live_workflow, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim]
|
||||
"""
|
||||
return _api_get_session(self, session_id)
|
||||
@api.delete("/api/v1/sessions/{session_id}", dependencies=[Depends(get_api_key)])
|
||||
def delete_session(session_id: str) -> dict[str, str]:
|
||||
return _api_delete_session(self, session_id)
|
||||
@api.get("/api/v1/context", dependencies=[Depends(get_api_key)])
|
||||
def get_context() -> Metadata:
|
||||
"""
|
||||
[C: src/fuzzy_anchor.py:FuzzyAnchor.create_slice]
|
||||
"""
|
||||
return _api_get_context(self)
|
||||
@api.get("/api/v1/token_stats", dependencies=[Depends(get_api_key)])
|
||||
def token_stats() -> Metadata:
|
||||
@@ -2914,17 +2885,12 @@ class AppController:
|
||||
return api
|
||||
|
||||
def clear_last_error(self) -> None:
|
||||
"""Reset last_error after a successful response cycle.
|
||||
[C: src/vendor_state.py:get_vendor_state]
|
||||
"""
|
||||
"""Reset last_error after a successful response cycle."""
|
||||
self.last_error = None
|
||||
|
||||
#region: Layout
|
||||
|
||||
def _cb_save_workspace_profile(self, name: str, scope: str = 'project') -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_save_workspace_profile_modal]
|
||||
"""
|
||||
if not hasattr(self, '_app') or not self._app:
|
||||
return
|
||||
profile = self._app._capture_workspace_profile(name)
|
||||
@@ -2933,18 +2899,12 @@ class AppController:
|
||||
self._app.workspace_profiles = self.workspace_profiles
|
||||
|
||||
def _cb_delete_workspace_profile(self, name: str, scope: str = 'project') -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._show_menus]
|
||||
"""
|
||||
self.workspace_manager.delete_profile(name, scope=scope)
|
||||
self.workspace_profiles = self.workspace_manager.load_all_profiles()
|
||||
if hasattr(self, '_app') and self._app:
|
||||
self._app.workspace_profiles = self.workspace_profiles
|
||||
|
||||
def _cb_load_workspace_profile(self, name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._show_menus]
|
||||
"""
|
||||
if name in self.workspace_profiles:
|
||||
profile = self.workspace_profiles[name]
|
||||
if hasattr(self, '_app') and self._app:
|
||||
@@ -2955,9 +2915,6 @@ class AppController:
|
||||
#region: Serialization
|
||||
|
||||
def _flush_to_project(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_entry_controls, src/gui_2.py:App._render_main_interface, src/gui_2.py:App._render_projects_panel, src/gui_2.py:App._show_menus, tests/test_view_presets.py:test_save_view_preset]
|
||||
"""
|
||||
proj = self.project
|
||||
proj.setdefault("output", {})["output_dir"] = self.ui_output_dir
|
||||
proj.setdefault("files", {})["base_dir"] = self.ui_files_base_dir
|
||||
@@ -3003,9 +2960,6 @@ class AppController:
|
||||
)
|
||||
|
||||
def _flush_to_config(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_entry_controls, src/gui_2.py:App._render_main_interface, src/gui_2.py:App._render_projects_panel, src/gui_2.py:App._render_theme_panel, src/gui_2.py:App._show_menus, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_app_controller_flush_saves_prompts]
|
||||
"""
|
||||
self.config["ai"] = {
|
||||
"provider": self.current_provider,
|
||||
"model": self.current_model,
|
||||
@@ -3085,9 +3039,6 @@ class AppController:
|
||||
}
|
||||
|
||||
def _refresh_api_metrics(self, payload: Metadata, md_content: str | None = None) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_updates.py:test_telemetry_data_updates_correctly]
|
||||
"""
|
||||
if "latency" in payload:
|
||||
self.session_usage["last_latency"] = payload["latency"]
|
||||
if "usage" in payload and "percentage" in payload["usage"]:
|
||||
@@ -3112,9 +3063,7 @@ class AppController:
|
||||
self._update_cached_stats()
|
||||
|
||||
def set_vendor_quota(self, provider: str, remaining_pct: float, reset_at: str = "") -> None:
|
||||
"""Update vendor quota state from a quota-bearing API response.
|
||||
[C: src/vendor_state.py:get_vendor_state]
|
||||
"""
|
||||
"""Update vendor quota state from a quota-bearing API response."""
|
||||
self.vendor_quota = {"provider": provider, "remaining_pct": remaining_pct, "reset_at": reset_at}
|
||||
|
||||
def _recalculate_session_usage(self) -> None:
|
||||
@@ -3205,8 +3154,6 @@ class AppController:
|
||||
|
||||
def _switch_project(self, path: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_projects_panel]
|
||||
|
||||
Non-blocking: returns immediately, marks the controller as stale,
|
||||
and runs the actual save/load work in a background thread so the
|
||||
render loop keeps drawing and lightweight UI interactions (scrolling,
|
||||
@@ -3231,9 +3178,6 @@ class AppController:
|
||||
|
||||
def _refresh_from_project(self) -> None:
|
||||
# Deserialize FileItems in files.paths
|
||||
"""
|
||||
[C: tests/test_mma_dashboard_refresh.py:test_mma_dashboard_initialization_refresh, tests/test_mma_dashboard_refresh.py:test_mma_dashboard_refresh, tests/test_view_presets.py:test_load_presets_from_project_legacy_dict, tests/test_view_presets.py:test_load_presets_from_project_list]
|
||||
"""
|
||||
raw_paths = self.project.get("files", {}).get("paths", [])
|
||||
self.files = []
|
||||
for p in raw_paths:
|
||||
@@ -3342,9 +3286,6 @@ class AppController:
|
||||
return False
|
||||
|
||||
def _save_active_project(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App.delete_context_preset, src/gui_2.py:App.save_context_preset]
|
||||
"""
|
||||
result = self._save_active_project_result()
|
||||
if not result.ok:
|
||||
err = result.errors[0]
|
||||
@@ -3377,9 +3318,6 @@ class AppController:
|
||||
#region: Context
|
||||
|
||||
def _cb_reset_base_prompt(self, user_data=None) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_system_prompts_panel]
|
||||
"""
|
||||
self.ui_base_system_prompt = ai_client._SYSTEM_PROMPT
|
||||
self.ui_use_default_base_prompt = False
|
||||
|
||||
@@ -3388,15 +3326,9 @@ class AppController:
|
||||
self.ai_status = 'summary cache cleared'
|
||||
|
||||
def _cb_show_base_prompt_diff(self, user_data=None) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_system_prompts_panel]
|
||||
"""
|
||||
self._show_base_prompt_diff_modal = True
|
||||
|
||||
def _cb_clear_summary_cache(self, user_data=None) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_files_panel]
|
||||
"""
|
||||
from src import summarize
|
||||
summarize._summary_cache.clear()
|
||||
self._push_mma_state_update()
|
||||
@@ -3434,9 +3366,6 @@ class AppController:
|
||||
self._cached_tool_stats = dict(self._tool_stats)
|
||||
|
||||
def clear_cache(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_cache_panel]
|
||||
"""
|
||||
from src import ai_client
|
||||
ai_client.cleanup()
|
||||
self._update_cached_stats()
|
||||
@@ -3651,9 +3580,6 @@ class AppController:
|
||||
self.ui_project_preset_name = name
|
||||
|
||||
def _cb_save_preset(self, name, content, scope):
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_preset_manager_content]
|
||||
"""
|
||||
if not name or not name.strip():
|
||||
raise ValueError("Preset name cannot be empty or whitespace.")
|
||||
preset = Preset(
|
||||
@@ -3664,31 +3590,19 @@ class AppController:
|
||||
self.presets = self.preset_manager.load_all()
|
||||
|
||||
def _cb_delete_preset(self, name, scope):
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_preset_manager_content]
|
||||
"""
|
||||
self.preset_manager.delete_preset(name, scope)
|
||||
self.presets = self.preset_manager.load_all()
|
||||
|
||||
def _cb_save_tool_preset(self, name, categories, scope):
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_tool_preset_manager_content]
|
||||
"""
|
||||
preset = ToolPreset(name=name, categories=categories)
|
||||
self.tool_preset_manager.save_preset(preset, scope)
|
||||
self.tool_presets = self.tool_preset_manager.load_all_presets()
|
||||
|
||||
def _cb_delete_tool_preset(self, name, scope):
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_tool_preset_manager_content]
|
||||
"""
|
||||
self.tool_preset_manager.delete_preset(name, scope)
|
||||
self.tool_presets = self.tool_preset_manager.load_all_presets()
|
||||
|
||||
def _cb_save_bias_profile(self, profile: BiasProfile, scope: str = "project"):
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_tool_preset_manager_content]
|
||||
"""
|
||||
self.tool_preset_manager.save_bias_profile(profile, scope)
|
||||
self.bias_profiles = self.tool_preset_manager.load_all_bias_profiles()
|
||||
|
||||
@@ -3697,23 +3611,14 @@ class AppController:
|
||||
self.bias_profiles = self.tool_preset_manager.load_all_bias_profiles()
|
||||
|
||||
def _cb_save_persona(self, persona: Persona, scope: str = "project") -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_persona_editor_window]
|
||||
"""
|
||||
self.persona_manager.save_persona(persona, scope)
|
||||
self.personas = self.persona_manager.load_all()
|
||||
|
||||
def _cb_delete_persona(self, name: str, scope: str = "project") -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_persona_editor_window]
|
||||
"""
|
||||
self.persona_manager.delete_persona(name, scope)
|
||||
self.personas = self.persona_manager.load_all()
|
||||
|
||||
def _cb_save_view_preset(self, name: str, f_item: FileItem) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_context_files_table, tests/test_view_presets.py:test_save_view_preset]
|
||||
"""
|
||||
preset = NamedViewPreset(
|
||||
name=name,
|
||||
view_mode=f_item.view_mode,
|
||||
@@ -3729,9 +3634,6 @@ class AppController:
|
||||
self._flush_to_project()
|
||||
|
||||
def _cb_apply_view_preset(self, name: str, f_item: FileItem) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_context_files_table, tests/test_view_presets.py:test_apply_view_preset]
|
||||
"""
|
||||
preset = next((vp for vp in self.view_presets if vp.name == name), None)
|
||||
if preset:
|
||||
f_item.view_mode = preset.view_mode
|
||||
@@ -3739,9 +3641,6 @@ class AppController:
|
||||
f_item.custom_slices = copy.deepcopy(preset.custom_slices)
|
||||
|
||||
def _cb_delete_view_preset(self, name: str) -> None:
|
||||
"""
|
||||
[C: tests/test_view_presets.py:test_delete_view_preset]
|
||||
"""
|
||||
self.view_presets = [vp for vp in self.view_presets if vp.name != name]
|
||||
self._flush_to_project()
|
||||
|
||||
@@ -3756,17 +3655,11 @@ class AppController:
|
||||
self.ui_disc_new_name_input = ""
|
||||
|
||||
def _get_discussion_names(self) -> list[str]:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_selector, src/gui_2.py:App._render_theme_panel]
|
||||
"""
|
||||
disc_sec = self.project.get("discussion", {})
|
||||
discussions = disc_sec.get("discussions", {})
|
||||
return sorted(discussions.keys())
|
||||
|
||||
def _switch_discussion(self, name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_selector, src/gui_2.py:App._render_takes_panel, src/gui_2.py:App._render_theme_panel]
|
||||
"""
|
||||
self._flush_disc_entries_to_project()
|
||||
disc_sec = self.project.get("discussion", {})
|
||||
discussions = disc_sec.get("discussions", {})
|
||||
@@ -3790,9 +3683,6 @@ class AppController:
|
||||
self.ai_status = f"discussion: {name}"
|
||||
|
||||
def _flush_disc_entries_to_project(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_selector, src/gui_2.py:App._render_theme_panel]
|
||||
"""
|
||||
history_strings = [project_manager.entry_to_str(e) for e in self.disc_entries]
|
||||
if self.active_track and self._track_discussion_active:
|
||||
project_manager.save_track_history(self.active_track.id, history_strings, self.active_project_root)
|
||||
@@ -3807,10 +3697,7 @@ class AppController:
|
||||
disc_data["sent_system_prompt"] = getattr(self, "discussion_sent_system_prompt", "")
|
||||
|
||||
def _handle_approve_ask(self) -> None:
|
||||
"""
|
||||
Responds with approval for a pending /api/ask request.
|
||||
[C: src/gui_2.py:App._handle_approve_ask, src/gui_2.py:App._render_mma_modals]
|
||||
"""
|
||||
"""Responds with approval for a pending /api/ask request."""
|
||||
if not self._ask_request_id: return
|
||||
request_id = self._ask_request_id
|
||||
|
||||
@@ -3829,10 +3716,7 @@ class AppController:
|
||||
self._ask_tool_data = None
|
||||
|
||||
def _handle_reject_ask(self) -> None:
|
||||
"""
|
||||
Responds with rejection for a pending /api/ask request.
|
||||
[C: src/gui_2.py:App._render_mma_modals]
|
||||
"""
|
||||
"""Responds with rejection for a pending /api/ask request."""
|
||||
if not self._ask_request_id: return
|
||||
request_id = self._ask_request_id
|
||||
|
||||
@@ -3851,10 +3735,7 @@ class AppController:
|
||||
self._ask_tool_data = None
|
||||
|
||||
def _handle_reset_session(self) -> None:
|
||||
"""
|
||||
Logic for resetting the AI session and GUI state.
|
||||
[C: src/gui_2.py:App._render_message_panel]
|
||||
"""
|
||||
"""Logic for resetting the AI session and GUI state."""
|
||||
ai_client.reset_session()
|
||||
ai_client.clear_comms_log()
|
||||
self._tool_log.clear()
|
||||
@@ -4021,18 +3902,12 @@ class AppController:
|
||||
self.submit_io(worker)
|
||||
|
||||
def _handle_generate_send(self) -> None:
|
||||
"""
|
||||
Logic for the 'Gen + Send' action.
|
||||
[C: src/gui_2.py:App._render_message_panel, src/gui_2.py:App._render_synthesis_panel, src/gui_2.py:App._render_takes_panel, tests/test_gui_events_v2.py:test_handle_generate_send_pushes_event, tests/test_symbol_parsing.py:test_handle_generate_send_appends_definitions, tests/test_symbol_parsing.py:test_handle_generate_send_no_symbols]
|
||||
"""
|
||||
"""Logic for the 'Gen + Send' action."""
|
||||
if self.is_project_stale():
|
||||
self.ai_status = "project switch in progress; AI ops disabled"
|
||||
return
|
||||
|
||||
def worker() -> "Result[None]":
|
||||
"""
|
||||
[C: tests/test_symbol_parsing.py:test_handle_generate_send_appends_definitions, tests/test_symbol_parsing.py:test_handle_generate_send_no_symbols]
|
||||
"""
|
||||
try:
|
||||
md, path, file_items, stable_md, disc_text = self._do_generate()
|
||||
self._last_stable_md = stable_md
|
||||
@@ -4064,10 +3939,7 @@ class AppController:
|
||||
self.submit_io(worker)
|
||||
|
||||
def _do_generate(self) -> tuple[str, Path, list[FileItem], str, str]:
|
||||
"""
|
||||
Returns (full_md, output_path, file_items, stable_md, discussion_text).
|
||||
[C: src/gui_2.py:App._show_menus, tests/test_context_composition_decoupled.py:test_do_generate_uses_context_files, tests/test_tiered_aggregation.py:test_app_controller_do_generate_uses_persona_strategy]
|
||||
"""
|
||||
"""Returns (full_md, output_path, file_items, stable_md, discussion_text)."""
|
||||
self._flush_to_project()
|
||||
self._flush_to_config()
|
||||
self.save_config()
|
||||
@@ -4114,18 +3986,12 @@ class AppController:
|
||||
return full_md, path, file_items, stable_md, discussion_text
|
||||
|
||||
def _handle_md_only(self) -> None:
|
||||
"""
|
||||
Logic for the 'MD Only' action.
|
||||
[C: src/gui_2.py:App._render_message_panel]
|
||||
"""
|
||||
"""Logic for the 'MD Only' action."""
|
||||
if self.is_project_stale():
|
||||
self.ai_status = "project switch in progress; MD generation disabled"
|
||||
return
|
||||
|
||||
def worker() -> "Result[None]":
|
||||
"""
|
||||
[C: tests/test_symbol_parsing.py:test_handle_generate_send_appends_definitions, tests/test_symbol_parsing.py:test_handle_generate_send_no_symbols]
|
||||
"""
|
||||
try:
|
||||
md, path, *_ = self._do_generate()
|
||||
self.last_md = md
|
||||
@@ -4144,9 +4010,6 @@ class AppController:
|
||||
self.submit_io(worker)
|
||||
|
||||
def _create_discussion(self, name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_metadata, src/gui_2.py:App._render_synthesis_panel, src/gui_2.py:App._render_takes_panel]
|
||||
"""
|
||||
disc_sec = self.project.setdefault("discussion", {})
|
||||
discussions = disc_sec.setdefault("discussions", {})
|
||||
if name in discussions:
|
||||
@@ -4160,9 +4023,6 @@ class AppController:
|
||||
self._switch_discussion(name)
|
||||
|
||||
def _branch_discussion(self, index: int) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_entry]
|
||||
"""
|
||||
self._flush_disc_entries_to_project()
|
||||
# Generate a unique branch name
|
||||
base_name = self.active_discussion.split("_take_")[0]
|
||||
@@ -4178,9 +4038,6 @@ class AppController:
|
||||
self._switch_discussion(new_name)
|
||||
|
||||
def _rename_discussion(self, old_name: str, new_name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_metadata]
|
||||
"""
|
||||
disc_sec = self.project.get("discussion", {})
|
||||
discussions = disc_sec.get("discussions", {})
|
||||
if old_name not in discussions:
|
||||
@@ -4194,9 +4051,6 @@ class AppController:
|
||||
disc_sec["active"] = new_name
|
||||
|
||||
def _delete_discussion(self, name: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_discussion_metadata]
|
||||
"""
|
||||
disc_sec = self.project.get("discussion", {})
|
||||
discussions = disc_sec.get("discussions", {})
|
||||
if len(discussions) <= 1:
|
||||
@@ -4214,10 +4068,7 @@ class AppController:
|
||||
#region: Operations
|
||||
|
||||
def _handle_request_event(self, event: events.UserRequestEvent) -> None:
|
||||
"""
|
||||
Processes a UserRequestEvent by calling the AI client.
|
||||
[C: tests/test_live_gui_integration_v2.py:test_user_request_error_handling, tests/test_live_gui_integration_v2.py:test_user_request_integration_flow, tests/test_rag_integration.py:test_rag_integration]
|
||||
"""
|
||||
"""Processes a UserRequestEvent by calling the AI client."""
|
||||
self.ai_status = 'sending...'
|
||||
|
||||
user_msg = event.prompt
|
||||
@@ -4295,9 +4146,6 @@ class AppController:
|
||||
self._ai_status = f"error: {err.ui_message()}"
|
||||
|
||||
def _on_tool_log(self, script: str, result: str) -> None:
|
||||
"""
|
||||
[C: tests/test_app_controller_offloading.py:test_on_tool_log_offloading]
|
||||
"""
|
||||
session_logger.log_tool_call(script, result, None)
|
||||
session_logger.log_tool_output_result(result)
|
||||
source_tier = ai_client.get_current_tier_result().data
|
||||
@@ -4325,9 +4173,6 @@ class AppController:
|
||||
return optimized
|
||||
|
||||
def _on_api_event(self, event_name: str = "generic_event", **kwargs: Any) -> None:
|
||||
"""
|
||||
[C: tests/test_gui_updates.py:test_gui_updates_on_event]
|
||||
"""
|
||||
payload = kwargs.get("payload", {})
|
||||
# Push to background event queue, NOT GUI queue
|
||||
self.event_queue.put("refresh_api_metrics", payload)
|
||||
@@ -4347,9 +4192,6 @@ class AppController:
|
||||
if self._ai_status not in ("sending...", "streaming..."):
|
||||
self._ai_status = "streaming..."
|
||||
def _on_comms_entry(self, entry: Metadata) -> None:
|
||||
"""
|
||||
[C: tests/test_app_controller_offloading.py:test_on_comms_entry_tool_result_offloading]
|
||||
"""
|
||||
optimized_entry = self._offload_entry_payload(entry)
|
||||
session_logger.log_comms(optimized_entry)
|
||||
entry["local_ts"] = time.time()
|
||||
@@ -4446,9 +4288,6 @@ class AppController:
|
||||
self._pending_comms.append(entry)
|
||||
|
||||
def _append_tool_log(self, script: str, result: str, source_tier: str | None = None, elapsed_ms: float = 0.0) -> None:
|
||||
"""
|
||||
[C: tests/test_mma_agent_focus_phase1.py:test_append_tool_log_dict_has_source_tier, tests/test_mma_agent_focus_phase1.py:test_append_tool_log_dict_keys, tests/test_mma_agent_focus_phase1.py:test_append_tool_log_stores_dict]
|
||||
"""
|
||||
self._tool_log.append({"script": script, "result": result, "ts": time.time(), "source_tier": source_tier})
|
||||
tool_name = self._extract_tool_name(script)
|
||||
is_failure = "REJECTED" in result or "Error" in result or "error" in result.lower()
|
||||
@@ -4467,9 +4306,6 @@ class AppController:
|
||||
self._scroll_tool_calls_to_bottom = True
|
||||
|
||||
def _confirm_and_run(self, script: str, base_dir: str, qa_callback: Optional[Callable[[str], str]] = None, patch_callback: Optional[Callable[[str, str], Result[str]]] = None) -> str:
|
||||
"""
|
||||
[C: tests/test_arch_boundary_phase2.py:TestArchBoundaryPhase2.test_mutating_tool_triggers_callback, tests/test_arch_boundary_phase2.py:TestArchBoundaryPhase2.test_rejection_prevents_dispatch]
|
||||
"""
|
||||
if self.test_hooks_enabled and not getattr(self, "ui_manual_approve", False):
|
||||
self.ai_status = "running powershell..."
|
||||
output = shell_runner.run_powershell(script, base_dir, qa_callback=qa_callback, patch_callback=patch_callback)
|
||||
@@ -4627,9 +4463,6 @@ class AppController:
|
||||
asyncio.run(self.refresh_external_mcps())
|
||||
|
||||
def _cb_plan_epic(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_mma_epic_planner, tests/test_mma_orchestration_gui.py:test_cb_plan_epic_launches_thread]
|
||||
"""
|
||||
def _bg_task() -> "Result[None]":
|
||||
try:
|
||||
self.ai_status = "Planning Epic (Tier 1)..."
|
||||
@@ -4681,9 +4514,6 @@ class AppController:
|
||||
self.submit_io(_bg_task)
|
||||
|
||||
def _cb_accept_tracks(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_track_proposal_modal]
|
||||
"""
|
||||
self._show_track_proposal_modal = False
|
||||
|
||||
def _bg_task() -> "Result[None]":
|
||||
@@ -4728,9 +4558,6 @@ class AppController:
|
||||
self.submit_io(_bg_task)
|
||||
|
||||
def _cb_start_track(self, user_data: Any = None) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_track_proposal_modal]
|
||||
"""
|
||||
if isinstance(user_data, str):
|
||||
# If track_id is provided directly
|
||||
track_id = user_data
|
||||
@@ -4882,9 +4709,6 @@ class AppController:
|
||||
return Result(data=None, errors=[err])
|
||||
|
||||
def _cb_ticket_retry(self, ticket_id: str) -> None:
|
||||
"""
|
||||
[C: tests/test_mma_ticket_actions.py:test_cb_ticket_retry]
|
||||
"""
|
||||
for t in self.active_tickets:
|
||||
if t.id == ticket_id:
|
||||
t.status = 'todo'
|
||||
@@ -4892,9 +4716,6 @@ class AppController:
|
||||
self.event_queue.put("mma_retry", {"ticket_id": ticket_id})
|
||||
|
||||
def _cb_ticket_skip(self, ticket_id: str) -> None:
|
||||
"""
|
||||
[C: tests/test_mma_ticket_actions.py:test_cb_ticket_skip]
|
||||
"""
|
||||
for t in self.active_tickets:
|
||||
if t.id == ticket_id:
|
||||
t.status = 'skipped'
|
||||
@@ -4914,10 +4735,7 @@ class AppController:
|
||||
self.event_queue.put("mma_retry", {"ticket_id": ticket_id})
|
||||
|
||||
def kill_worker(self, worker_id: str) -> None:
|
||||
"""
|
||||
Aborts a running worker.
|
||||
[C: src/gui_2.py:App._cb_kill_ticket, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread]
|
||||
"""
|
||||
"""Aborts a running worker."""
|
||||
engine = self.engines.get(self.active_track.id if self.active_track else None)
|
||||
if engine:
|
||||
engine.kill_worker(worker_id)
|
||||
@@ -4987,9 +4805,6 @@ class AppController:
|
||||
)])
|
||||
|
||||
def _cb_run_conductor_setup(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_mma_conductor_setup, tests/test_gui_phase3.py:test_conductor_setup_scan]
|
||||
"""
|
||||
base = paths.get_conductor_dir(project_path=self.active_project_root)
|
||||
if not base.exists():
|
||||
self.ui_conductor_setup_summary = f"Error: {base}/ directory not found."
|
||||
@@ -5017,9 +4832,6 @@ class AppController:
|
||||
self.ui_conductor_setup_summary = "\n".join(summary)
|
||||
|
||||
def _cb_create_track(self, name: str, desc: str, track_type: str) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_mma_track_browser, tests/test_gui_phase3.py:test_create_track]
|
||||
"""
|
||||
if not name: return
|
||||
date_suffix = datetime.now().strftime("%Y%m%d")
|
||||
track_id = f"{name.lower().replace(' ', '_')}_{date_suffix}"
|
||||
@@ -5045,9 +4857,6 @@ class AppController:
|
||||
self.tracks = project_manager.get_all_tracks(self.active_project_root)
|
||||
|
||||
def _handle_mma_respond(self, approved: bool, payload: str | None = None, abort: bool = False, prompt: str | None = None, context_md: str | None = None) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._handle_approve_mma_step, src/gui_2.py:App._handle_approve_spawn, src/gui_2.py:App._render_mma_modals]
|
||||
"""
|
||||
if self._pending_mma_approvals:
|
||||
task = self._pending_mma_approvals.pop(0)
|
||||
dlg = task.get("dialog_container", [None])[0]
|
||||
@@ -5164,7 +4973,6 @@ class AppController:
|
||||
DEPRECATED (Phase 7 Task 7.4): legacy fire-and-forget wrapper. New
|
||||
callers should use `_push_mma_state_update_result()` which returns
|
||||
Result[None] and propagates errors via `_report_worker_error`.
|
||||
[C: tests/test_gui_phase4.py:test_push_mma_state_update, tests/test_ticket_queue.py:TestBulkOperations, tests/test_ticket_queue.py:TestReorder]
|
||||
"""
|
||||
result = self._push_mma_state_update_result()
|
||||
if not result.ok:
|
||||
@@ -5214,7 +5022,6 @@ class AppController:
|
||||
Otherwise, read from project state. The current code paths
|
||||
(mutate_dag, _cb_ticket_skip, etc.) populate self.active_tickets
|
||||
directly, so this method is the bootstrap path.
|
||||
[C: src/app_controller.py:_load_active_tickets call sites, tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads]
|
||||
"""
|
||||
self.active_tickets = []
|
||||
if getattr(self, "ui_project_execution_mode", None) == "beads":
|
||||
@@ -5260,7 +5067,6 @@ class AppController:
|
||||
from outside the controller (e.g. models.load_config) are an
|
||||
architectural smell and will be flagged by
|
||||
scripts/audit_no_models_config_io.py.
|
||||
[C: src/app_controller.py:AppController.__init__]
|
||||
"""
|
||||
self.config = load_config_from_disk()
|
||||
return self.config
|
||||
@@ -5272,7 +5078,6 @@ class AppController:
|
||||
controller (e.g. models.save_config) are an architectural smell
|
||||
and will be flagged by
|
||||
scripts/audit_no_models_config_io.py.
|
||||
[C: src/app_controller.py:AppController._cb_project_save, src/app_controller.py:AppController._do_generate]
|
||||
"""
|
||||
save_config_to_disk(self.config)
|
||||
#endregion: --- Config I/O (single source of truth) ---
|
||||
@@ -5283,18 +5088,12 @@ class AppController:
|
||||
|
||||
class MMAApprovalDialog:
|
||||
def __init__(self, ticket_id: str, payload: str) -> None:
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._payload = payload
|
||||
self._condition = threading.Condition()
|
||||
self._done = False
|
||||
self._approved = False
|
||||
|
||||
def wait(self) -> tuple[bool, str]:
|
||||
"""
|
||||
[C: src/mcp_client.py:StdioMCPServer.stop, src/multi_agent_conductor.py:confirm_execution, src/multi_agent_conductor.py:confirm_spawn, tests/conftest.py:live_gui, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_ai_server.py:test_server_handles_list_models, tests/test_ai_server.py:test_server_handles_unknown_method, tests/test_ai_server.py:test_server_loads_google_genai_quickly, tests/test_ai_server.py:test_server_outputs_ready_marker, tests/test_ai_server.py:test_server_starts_and_exits_cleanly, tests/test_conductor_engine_abort.py:worker, tests/test_parallel_execution.py:test_worker_pool_limit]
|
||||
"""
|
||||
start_time = time.time()
|
||||
with self._condition:
|
||||
while not self._done:
|
||||
@@ -5305,9 +5104,6 @@ class MMAApprovalDialog:
|
||||
|
||||
class MMASpawnApprovalDialog:
|
||||
def __init__(self, ticket_id: str, role: str, prompt: str, context_md: str) -> None:
|
||||
"""
|
||||
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
|
||||
"""
|
||||
self._prompt = prompt
|
||||
self._context_md = context_md
|
||||
self._condition = threading.Condition()
|
||||
@@ -5316,9 +5112,6 @@ class MMASpawnApprovalDialog:
|
||||
self._abort = False
|
||||
|
||||
def wait(self) -> Metadata:
|
||||
"""
|
||||
[C: src/mcp_client.py:StdioMCPServer.stop, src/multi_agent_conductor.py:confirm_execution, src/multi_agent_conductor.py:confirm_spawn, tests/conftest.py:live_gui, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_ai_server.py:test_server_handles_list_models, tests/test_ai_server.py:test_server_handles_unknown_method, tests/test_ai_server.py:test_server_loads_google_genai_quickly, tests/test_ai_server.py:test_server_outputs_ready_marker, tests/test_ai_server.py:test_server_starts_and_exits_cleanly, tests/test_conductor_engine_abort.py:worker, tests/test_parallel_execution.py:test_worker_pool_limit]
|
||||
"""
|
||||
start_time = time.time()
|
||||
with self._condition:
|
||||
while not self._done:
|
||||
@@ -5333,4 +5126,3 @@ class MMASpawnApprovalDialog:
|
||||
}
|
||||
|
||||
#endregion: MMA
|
||||
|
||||
|
||||
+5
-87
@@ -1477,8 +1477,6 @@ def _post_init_callback_result(app: "App") -> Result[None]:
|
||||
Result(data=None, errors=[ErrorInfo]) so the legacy wrapper can drain
|
||||
the error to self._startup_timeline_errors. On success, the lambda
|
||||
callback is registered and Result(data=None) is returned.
|
||||
|
||||
[C: src/gui_2.py:App._post_init (L612 legacy wrapper)]
|
||||
"""
|
||||
#Note(Ed): Exception(Thirdparty)
|
||||
try:
|
||||
@@ -1503,11 +1501,7 @@ def _install_default_layout_if_empty(src_ini: Path, dst_ini: Path) -> Result[boo
|
||||
current launch's render loop). On non-empty (user customized), returns
|
||||
Result(data=False) without overwriting. On OSError reading src or
|
||||
writing dst, returns Result(data=False, errors=[ErrorInfo]) so the
|
||||
legacy wrapper in App._post_init can drain to _startup_timeline_errors.
|
||||
|
||||
[C: src/gui_2.py:_install_default_layout_if_empty_result,
|
||||
src/gui_2.py:App._post_init,
|
||||
src/gui_2.py:App.run (pre-immapp disk write)]"""
|
||||
legacy wrapper in App._post_init can drain to _startup_timeline_errors."""
|
||||
try:
|
||||
dst_text: str = dst_ini.read_text(encoding="utf-8", errors="replace") if dst_ini.exists() else ""
|
||||
except OSError:
|
||||
@@ -1555,8 +1549,7 @@ def _apply_default_layout_to_session_result(src_text: str, src_ini: Path, dst_in
|
||||
the helper converts the exception to ErrorInfo instead of writing to
|
||||
stderr. The caller (_install_default_layout_if_empty) inspects the
|
||||
result and decides whether to propagate the error.
|
||||
|
||||
[C: src/gui_2.py:_install_default_layout_if_empty]"""
|
||||
"""
|
||||
try:
|
||||
imgui.load_ini_settings_from_memory(src_text)
|
||||
sys.stderr.write(f"[GUI] installed default layout: {src_ini} -> {dst_ini} (and applied to live session)\n")
|
||||
@@ -1578,8 +1571,7 @@ def _install_default_layout_if_empty_result(app: "App", src: Path, dst: Path) ->
|
||||
The wrapped function already returns Result[bool] and catches OSError
|
||||
internally; this wrapper exists for naming consistency and to give
|
||||
any future exception-logging policy a single hook point.
|
||||
|
||||
[C: src/gui_2.py:_install_default_layout_if_empty, src/gui_2.py:App._post_init]"""
|
||||
"""
|
||||
return _install_default_layout_if_empty(src, dst)
|
||||
|
||||
|
||||
@@ -1598,8 +1590,7 @@ def _install_default_layout_pre_run_result(app: "App") -> Result[bool]:
|
||||
|
||||
Returns Result[data=True] when installed, Result[data=False] when
|
||||
skipped (existing valid INI).
|
||||
|
||||
[C: src/gui_2.py:App.run, src/gui_2.py:App._post_init]"""
|
||||
"""
|
||||
# Skip in test mode: the test sandbox (sys.addaudithook registered by
|
||||
# tests/conftest.py) blocks writes outside ./tests/, and the dst path
|
||||
# is the project root which violates that allowlist. Production launches
|
||||
@@ -1649,8 +1640,6 @@ def _run_immapp_result(app: "App") -> Result[None]:
|
||||
(the canonical degradation drain), appends to _startup_timeline_errors,
|
||||
and returns. NO logging: logging is NOT a drain per the user's
|
||||
principle 2026-06-17.
|
||||
|
||||
[C: src/gui_2.py:App.run (L728 legacy wrapper)]
|
||||
"""
|
||||
#Note(Ed): Exception(Thirdparty)
|
||||
try:
|
||||
@@ -1670,8 +1659,6 @@ def _shutdown_save_ini_result(app: "App") -> Result[None]:
|
||||
App.shutdown into a Result-returning helper. On exception, converts to
|
||||
ErrorInfo (logging NOT a drain per the user's principle 2026-06-17). The
|
||||
legacy shutdown method drains to self._startup_timeline_errors.
|
||||
|
||||
[C: src/gui_2.py:App.shutdown (L1052 legacy wrapper)]
|
||||
"""
|
||||
#Note(Ed): Exception(Thirdparty)
|
||||
try:
|
||||
@@ -1693,8 +1680,6 @@ def _gui_func_entry_log_result(app: "App") -> Result[None]:
|
||||
OSError on the stderr stream), converts to ErrorInfo (logging NOT a drain
|
||||
per the user's principle 2026-06-17). The legacy _gui_func method
|
||||
drains to self._last_request_errors.
|
||||
|
||||
[C: src/gui_2.py:App._gui_func (L1152 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
init_ts = getattr(app.controller, "_init_start_ts", None)
|
||||
@@ -1718,8 +1703,6 @@ def _close_vscode_diff_terminate_result(app: "App") -> Result[None]:
|
||||
NOT a drain per the user's principle 2026-06-17). The legacy wrapper
|
||||
drains to self._last_request_errors and proceeds to set
|
||||
self._vscode_diff_process = None (preserving the original behavior).
|
||||
|
||||
[C: src/gui_2.py:App._close_vscode_diff (L1466 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
app._vscode_diff_process.terminate()
|
||||
@@ -1740,8 +1723,6 @@ def _focus_response_window_result() -> Result[None]:
|
||||
bundle error, IM_ASSERT), converts to ErrorInfo (logging NOT a drain per
|
||||
the user's principle 2026-06-17). The caller drains to
|
||||
app._last_request_errors.
|
||||
|
||||
[C: src/gui_2.py:render_main_interface (L1647 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
imgui.set_window_focus("Response") # type: ignore[call-arg]
|
||||
@@ -1763,8 +1744,6 @@ def _autosave_flush_result(app: "App") -> Result[None]:
|
||||
app._last_request_errors and continues with the GUI loop, preserving
|
||||
the original "don't disrupt the GUI loop" intent via the data plane
|
||||
rather than silent swallow.
|
||||
|
||||
[C: src/gui_2.py:render_main_interface (L1693 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
app._flush_to_project()
|
||||
@@ -1787,8 +1766,6 @@ def _on_warmup_complete_callback_result(app: "App", status: dict) -> Result[None
|
||||
per the user's principle 2026-06-17). The legacy callback drains to
|
||||
app.controller._worker_errors with the controller lock acquired on
|
||||
append (thread-safety critical per sub-track 4 spec).
|
||||
|
||||
[C: src/gui_2.py:_on_warmup_complete_callback (L4911 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
app._warmup_completion_ts = time.time()
|
||||
@@ -1822,8 +1799,6 @@ def _tier_stream_scroll_sync_result(app: "App", stream_key: str, content: str, i
|
||||
logging NOT a drain per the user's principle 2026-06-17. On exception,
|
||||
converts to ErrorInfo. The caller (render_tier_stream_panel) drains
|
||||
to app._last_request_errors.
|
||||
|
||||
[C: src/gui_2.py:render_tier_stream_panel (L6908 caller)]
|
||||
"""
|
||||
try:
|
||||
if len(content) != app._tier_stream_last_len.get(stream_key, -1):
|
||||
@@ -1846,8 +1821,6 @@ def _dag_cycle_check_result(app: "App") -> Result[bool]:
|
||||
On exception (bad ticket dict, dag engine failure), converts to
|
||||
ErrorInfo (logging NOT a drain per the user's principle 2026-06-17).
|
||||
The caller drains to app._last_request_errors.
|
||||
|
||||
[C: src/gui_2.py:render_task_dag_panel (L7271 caller)]
|
||||
"""
|
||||
from src.dag_engine import TrackDAG
|
||||
try:
|
||||
@@ -1873,8 +1846,6 @@ def _ticket_id_max_int_result(tid: str) -> Result[int]:
|
||||
malformed tickets via the data plane (logging NOT a drain per the
|
||||
user's principle 2026-06-17). The caller drains to
|
||||
app._last_request_errors.
|
||||
|
||||
[C: src/gui_2.py:render_task_dag_panel (L7315 caller)]
|
||||
"""
|
||||
try:
|
||||
return Result(data=int(tid[2:]))
|
||||
@@ -7704,8 +7675,6 @@ def _render_worker_error_indicator(app: "App") -> None:
|
||||
Visible only when app.controller._worker_errors is non-empty. Per the
|
||||
UI delegation pattern (conductor/product-guidelines.md), the function lives
|
||||
at module level and the App class wraps it as a thin delegation.
|
||||
|
||||
[C: src/gui_2.py:App._render_worker_error_indicator delegation wrapper]
|
||||
"""
|
||||
errs = getattr(app.controller, "_worker_errors", None)
|
||||
if not errs:
|
||||
@@ -7720,8 +7689,6 @@ def _render_last_request_errors_modal(app: "App") -> None:
|
||||
|
||||
Opens a modal only if errors accumulated during the request
|
||||
(app.controller._last_request_errors is non-empty).
|
||||
|
||||
[C: src/gui_2.py:App._render_last_request_errors_modal delegation wrapper]
|
||||
"""
|
||||
errs = getattr(app.controller, "_last_request_errors", None)
|
||||
if not errs:
|
||||
@@ -7791,8 +7758,6 @@ def _load_fonts_main_result(app: "App", font_path: str, font_size: float, config
|
||||
try/except from App._load_fonts into a Result-returning helper. On
|
||||
exception, sets app.main_font = None and returns Result(data=False,
|
||||
errors=[ErrorInfo]). On success, sets app.main_font to the loaded font.
|
||||
|
||||
[C: src/gui_2.py:App._load_fonts (L731 legacy wrapper)]
|
||||
"""
|
||||
from src.startup_profiler import startup_profiler
|
||||
try:
|
||||
@@ -7815,8 +7780,6 @@ def _load_fonts_mono_result(app: "App", font_size: float, config) -> Result[bool
|
||||
try/except from App._load_fonts into a Result-returning helper. On exception,
|
||||
sets app.mono_font = None and returns Result(data=False, errors=[ErrorInfo]).
|
||||
On success, sets app.mono_font to the loaded font.
|
||||
|
||||
[C: src/gui_2.py:App._load_fonts (L742 legacy wrapper)]
|
||||
"""
|
||||
from src.startup_profiler import startup_profiler
|
||||
try:
|
||||
@@ -7839,8 +7802,6 @@ def _render_main_interface_result(app: "App") -> Result[bool]:
|
||||
Extracts the OUTER render-loop try/except from App._gui_func into a
|
||||
Result-returning helper. The legacy wrapper MUST NOT break the render
|
||||
frame even if the error drain itself fails (per task constraint on L1123).
|
||||
|
||||
[C: src/gui_2.py:App._gui_func (L1123 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
if app.is_viewing_prior_session:
|
||||
@@ -7864,8 +7825,6 @@ def _show_menus_do_generate_result(app: "App") -> Result[bool]:
|
||||
App._show_menus into a Result-returning helper. On success, sets
|
||||
app.last_md, app.last_md_path, app.ai_status. On failure, sets
|
||||
app.ai_status to an error message.
|
||||
|
||||
[C: src/gui_2.py:App._show_menus (L1171 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
md, path, *_ = app._do_generate()
|
||||
@@ -7893,8 +7852,6 @@ def _show_menus_hwnd_result(app: "App") -> Result[int]:
|
||||
The data field is the resolved hwnd (int) so the legacy wrapper can
|
||||
pass it to subsequent win32gui calls without an additional app.hwnd
|
||||
instance attribute.
|
||||
|
||||
[C: src/gui_2.py:App._show_menus (L1197 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
import ctypes
|
||||
@@ -7920,8 +7877,6 @@ def _show_menus_is_max_result(app: "App", hwnd) -> Result[bool]:
|
||||
failure, returns Result(data=False, errors=[ErrorInfo]) - the data
|
||||
defaults to False (not maximized) matching the original except
|
||||
branch behavior.
|
||||
|
||||
[C: src/gui_2.py:App._show_menus (L1222 legacy wrapper)]
|
||||
"""
|
||||
global win32gui, win32con
|
||||
try:
|
||||
@@ -7949,8 +7904,6 @@ def _render_warmup_status_indicator_result(app: "App") -> Result[dict]:
|
||||
The data field is the status dict so the legacy wrapper can use it
|
||||
for rendering without an additional instance attribute. Errors drain
|
||||
to app.controller._worker_errors (worker error plane, lock-protected).
|
||||
|
||||
[C: src/gui_2.py:render_warmup_status_indicator (L4848 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
status = app.controller.warmup_status()
|
||||
@@ -7974,8 +7927,6 @@ def _handle_history_logic_result(app: "App") -> Result[bool]:
|
||||
On success, returns Result(data=True). On failure (any exception
|
||||
during _take_snapshot or the snapshot diff), returns Result(data=False,
|
||||
errors=[ErrorInfo]).
|
||||
|
||||
[C: src/gui_2.py:App._handle_history_logic (L1284 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
current = app._take_snapshot()
|
||||
@@ -8046,8 +7997,6 @@ def _render_persona_editor_save_result(app: "App") -> Result[bool]:
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-3
|
||||
modal pattern: data plane attribute; the modal itself is the UI surface).
|
||||
|
||||
[C: src/gui_2.py:render_persona_editor_window (L3398 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
import copy
|
||||
@@ -8085,8 +8034,6 @@ def _render_ast_inspector_outline_result(app: "App", f_path: str) -> Result[str]
|
||||
The data field carries the outline string so the legacy wrapper can
|
||||
iterate it without an additional instance attribute. Errors drain to
|
||||
app._last_request_errors (per FR-BC-3 modal pattern; data plane).
|
||||
|
||||
[C: src/gui_2.py:render_ast_inspector_modal (L3718 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
proj_dir = str(Path(app.controller.active_project_path).parent.resolve()) if getattr(app, 'controller', None) and app.controller.active_project_path else None
|
||||
@@ -8116,8 +8063,6 @@ def _render_ast_inspector_file_content_result(app: "App", f_path: str) -> Result
|
||||
- On success: app._cached_ast_file_lines = content.splitlines(); app.text_viewer_content = content
|
||||
- On failure: app._cached_ast_file_lines = ["Error loading file content."]; app.text_viewer_content = "Error loading file content."
|
||||
And drains errors to app._last_request_errors (per FR-BC-3 modal pattern).
|
||||
|
||||
[C: src/gui_2.py:render_ast_inspector_modal (L3740 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
content = mcp_client.read_file(f_path)
|
||||
@@ -8146,8 +8091,6 @@ def _populate_auto_slices_outline_result(app: "App", f_item, abs_path: str) -> R
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:App._populate_auto_slices (L1284 legacy wrapper)]
|
||||
"""
|
||||
f_path_lower = f_item.path.lower()
|
||||
try:
|
||||
@@ -8174,8 +8117,6 @@ def _populate_auto_slices_file_read_result(app: "App", f_item) -> Result[str]:
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:App._populate_auto_slices (L1293 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
with open(f_item.path, "r", encoding="utf-8") as f:
|
||||
@@ -8203,8 +8144,6 @@ def _apply_pending_patch_result(app: "App") -> Result[bool]:
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:App._apply_pending_patch (L1367 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
base_dir = str(app.controller.current_project_dir) if hasattr(app.controller, 'current_project_dir') else "."
|
||||
@@ -8245,8 +8184,6 @@ def _open_patch_in_external_editor_result(app: "App") -> Result[bool]:
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:App._open_patch_in_external_editor (L1393 legacy wrapper)]
|
||||
"""
|
||||
from src.external_editor import get_default_launcher, create_temp_modified_file
|
||||
import os
|
||||
@@ -8309,8 +8246,6 @@ def request_patch_from_tier4_result(app: "App", error: str, file_context: str) -
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:App.request_patch_from_tier4 (L1428 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
patch_text = ai_client.run_tier4_patch_generation(error, file_context)
|
||||
@@ -8352,8 +8287,6 @@ def _render_tool_preset_bias_save_result(app: "App") -> Result[bool]:
|
||||
The legacy wrapper (the imgui.button callback) drains errors to
|
||||
app._last_request_errors (per FR-BC-4 event-handler drain pattern;
|
||||
data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:render_tool_preset_manager_content (L3163 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
p = BiasProfile(
|
||||
@@ -8386,8 +8319,6 @@ def _render_context_batch_actions_preview_result(app: "App") -> Result[str]:
|
||||
The legacy wrapper (the imgui.button callback) drains errors to
|
||||
app._last_request_errors (per FR-BC-4 event-handler drain pattern;
|
||||
data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:render_context_batch_actions (L3582 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
app.controller.context_files = app.context_files
|
||||
@@ -8415,8 +8346,6 @@ def _render_operations_hub_external_editor_panel_result(app: "App") -> Result[bo
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:render_operations_hub (L5380 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
render_external_editor_panel(app)
|
||||
@@ -8440,8 +8369,6 @@ def _render_text_viewer_window_ced_result(app: "App") -> Result[bool]:
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:render_text_viewer_window (L5786 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
app._text_viewer_editor.set_text(app.text_viewer_content)
|
||||
@@ -8468,8 +8395,6 @@ def _render_external_editor_panel_config_result(app: "App") -> Result[bool]:
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:render_external_editor_panel (L5920 legacy wrapper)]
|
||||
"""
|
||||
from src.external_editor import get_default_launcher
|
||||
try:
|
||||
@@ -8531,8 +8456,6 @@ def _render_beads_tab_list_result(app: "App") -> Result[list]:
|
||||
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; data plane attribute).
|
||||
|
||||
[C: src/gui_2.py:render_beads_tab (L7208 legacy wrapper)]
|
||||
"""
|
||||
from src import beads_client
|
||||
try:
|
||||
@@ -8559,8 +8482,6 @@ def _worker_context_preview_result(app: "App") -> Result[None]:
|
||||
Result(data=None, errors=[ErrorInfo]). On success, sets app.context_preview_text
|
||||
to the generated markdown. The legacy worker() wrapper drains errors to
|
||||
app.controller._worker_errors (with the controller lock acquired on append).
|
||||
|
||||
[C: src/gui_2.py:_check_auto_refresh_context_preview (L4321 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
app.controller.context_files = app.context_files
|
||||
@@ -8589,8 +8510,6 @@ def _diag_layout_state_ini_text_result(app: "App", ini_path: str) -> Result[str]
|
||||
returns Result(data=ini_text) where ini_text is the file content. The
|
||||
legacy wrapper drains errors to app._startup_timeline_errors (startup
|
||||
callback drain plane).
|
||||
|
||||
[C: src/gui_2.py:App._diag_layout_state (L591 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
with open(ini_path, encoding="utf-8") as _f:
|
||||
@@ -8615,8 +8534,6 @@ def _capture_workspace_profile_ini_result(app: "App") -> Result[str]:
|
||||
returns Result(data=ini_str) where ini_str is the serialized INI content.
|
||||
The legacy wrapper drains errors to app._last_request_errors (per FR-BC-4
|
||||
event-handler drain pattern; this site is a property setter on the App).
|
||||
|
||||
[C: src/gui_2.py:App._capture_workspace_profile (L897 legacy wrapper)]
|
||||
"""
|
||||
try:
|
||||
ini = str(imgui.save_ini_settings_to_memory() or "")
|
||||
@@ -8968,4 +8885,5 @@ def _get_vendor_state_metrics(app: Any) -> list[Any]:
|
||||
tooltip = err.get("message", "No error since session start.") if err else "No error since session start."
|
||||
))
|
||||
return out
|
||||
|
||||
#endregion: Vendor State Metrics
|
||||
|
||||
Reference in New Issue
Block a user