feat(sdm): inject structural dependency mapping tags across codebase

Adds [C: caller] tags to functions/methods and [M: mutation] / [U: usage] tags to class variables based on cross-module call analysis.
This commit is contained in:
2026-05-13 22:35:41 -04:00
parent 5bb3a9026f
commit b5e512f483
110 changed files with 1673 additions and 1008 deletions
+2 -1
View File
@@ -102,7 +102,7 @@ class BaseSimulation:
def get_value(self, tag: str) -> Any: def get_value(self, tag: str) -> Any:
""" """
[C: simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/smoke_status_hook.py:test_status_hook, tests/smoke_status_hook.py:wait_for_value, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_mma.py:test_visual_mma_components, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration] [C: simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/smoke_status_hook.py:test_status_hook, tests/smoke_status_hook.py:wait_for_value, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration]
""" """
return self.client.get_value(tag) return self.client.get_value(tag)
@@ -128,6 +128,7 @@ class BaseSimulation:
def run_sim(sim_class: type) -> None: def run_sim(sim_class: type) -> None:
""" """
Helper to run a simulation class standalone. Helper to run a simulation class standalone.
[C: simulation/sim_context.py:module, simulation/sim_execution.py:module, simulation/sim_tools.py:module] [C: simulation/sim_context.py:module, simulation/sim_execution.py:module, simulation/sim_tools.py:module]
""" """
+2
View File
@@ -60,6 +60,7 @@ class UserSimAgent:
def generate_response(self, conversation_history: list[dict]) -> str: def generate_response(self, conversation_history: list[dict]) -> str:
""" """
Generates a human-like response based on the conversation history. Generates a human-like response based on the conversation history.
conversation_history: list of dicts with 'role' and 'content' conversation_history: list of dicts with 'role' and 'content'
[C: simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async] [C: simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async]
@@ -79,6 +80,7 @@ class UserSimAgent:
def perform_action_with_delay(self, action_func: Callable, *args: Any, **kwargs: Any) -> Any: def perform_action_with_delay(self, action_func: Callable, *args: Any, **kwargs: Any) -> Any:
""" """
Executes an action with a human-like delay if enabled. Executes an action with a human-like delay if enabled.
[C: tests/test_user_agent.py:test_perform_action_with_delay] [C: tests/test_user_agent.py:test_perform_action_with_delay]
""" """
+19 -7
View File
@@ -61,7 +61,10 @@ def resolve_paths(base_dir: Path, entry: str) -> list[Path]:
return sorted(filtered) return sorted(filtered)
def group_files_by_dir(files: list[Any]) -> dict[str, list[Any]]: def group_files_by_dir(files: list[Any]) -> dict[str, list[Any]]:
"""Groups FileItem objects by their relative directory path.""" """
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]
"""
grouped = {} grouped = {}
for f in files: for f in files:
path_str = f.path if hasattr(f, 'path') else str(f) path_str = f.path if hasattr(f, 'path') else str(f)
@@ -76,7 +79,10 @@ def group_files_by_dir(files: list[Any]) -> dict[str, list[Any]]:
return grouped return grouped
def compute_file_stats(abs_path: str) -> dict[str, int]: def compute_file_stats(abs_path: str) -> dict[str, int]:
"""Computes lines and basic AST stats for a file.""" """
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]
"""
stats = {"lines": 0, "ast_elements": 0} stats = {"lines": 0, "ast_elements": 0}
try: try:
with open(abs_path, 'r', encoding='utf-8') as f: with open(abs_path, 'r', encoding='utf-8') as f:
@@ -97,6 +103,7 @@ def build_discussion_section(history: list[Any]) -> str:
""" """
Builds a markdown section for discussion history. Builds a markdown section for discussion history.
Handles both legacy list[str] and new list[dict]. Handles both legacy list[str] and new list[dict].
""" """
@@ -133,6 +140,7 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
""" """
Return a list of dicts describing each file, for use by ai_client when it Return a list of dicts describing each file, for use by ai_client when it
wants to upload individual files rather than inline everything as markdown. wants to upload individual files rather than inline everything as markdown.
@@ -146,7 +154,7 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
auto_aggregate : bool auto_aggregate : bool
force_full : bool force_full : bool
view_mode : str (summary, full, skeleton, outline, none) 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_tiered_context.py:test_build_file_items_with_tiers] [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"): with get_monitor().scope("build_file_items"):
items: list[dict[str, Any]] = [] items: list[dict[str, Any]] = []
@@ -245,8 +253,9 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
def _build_files_section_from_items(file_items: list[dict[str, Any]]) -> str: def _build_files_section_from_items(file_items: list[dict[str, Any]]) -> str:
""" """
Build the files markdown section from pre-read file items (avoids double I/O). Build the files markdown section from pre-read file items (avoids double I/O).
[C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_ui_summary_only_removal.py:test_aggregate_from_items_respects_auto_aggregate] [C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_context_composition_phase6.py:test_files_section_rendering, tests/test_tiered_context.py:test_build_files_section_with_dicts, tests/test_ui_summary_only_removal.py:test_aggregate_from_items_respects_auto_aggregate]
""" """
sections = [] sections = []
for item in file_items: for item in file_items:
@@ -323,6 +332,7 @@ def build_markdown_from_items(file_items: list[dict[str, Any]], screenshot_base_
def build_markdown_no_history(file_items: list[dict[str, Any]], screenshot_base_dir: Path, screenshots: list[str], summary_only: bool = False, aggregation_strategy: str = "auto") -> str: def build_markdown_no_history(file_items: list[dict[str, Any]], screenshot_base_dir: Path, screenshots: list[str], summary_only: bool = False, aggregation_strategy: str = "auto") -> str:
""" """
Build markdown with only files + screenshots (no history). Used for stable caching. Build markdown with only files + screenshots (no history). Used for stable caching.
[C: src/app_controller.py:AppController._do_generate, tests/test_history_management.py:test_aggregate_blacklist] [C: src/app_controller.py:AppController._do_generate, tests/test_history_management.py:test_aggregate_blacklist]
""" """
@@ -331,6 +341,7 @@ def build_markdown_no_history(file_items: list[dict[str, Any]], screenshot_base_
def build_discussion_text(history: list[str]) -> str: def build_discussion_text(history: list[str]) -> str:
""" """
Build just the discussion history section text. Returns empty string if no history. Build just the discussion history section text. Returns empty string if no history.
[C: src/app_controller.py:AppController._do_generate, tests/test_history_management.py:test_aggregate_includes_segregated_history] [C: src/app_controller.py:AppController._do_generate, tests/test_history_management.py:test_aggregate_includes_segregated_history]
""" """
@@ -342,9 +353,10 @@ def build_tier3_context(file_items: list[dict[str, Any]], screenshot_base_dir: P
""" """
Tier 3 Context: Execution/Worker. Tier 3 Context: Execution/Worker.
Full content for focus_files and files with tier=3, summaries/skeletons for others. 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_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] [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"): with get_monitor().scope("build_tier3_context"):
focus_set = set(focus_files) focus_set = set(focus_files)
@@ -446,7 +458,7 @@ def build_markdown(base_dir: Path, files: list[str | dict[str, Any]], screenshot
def run(config: dict[str, Any], aggregation_strategy: str = "auto") -> tuple[str, Path, list[dict[str, Any]]]: def run(config: dict[str, Any], aggregation_strategy: str = "auto") -> tuple[str, Path, list[dict[str, Any]]]:
""" """
[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/project_manager.py:get_git_log, 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] [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") namespace = config.get("project", {}).get("name")
if not namespace: if not namespace:
@@ -472,7 +484,7 @@ def run(config: dict[str, Any], aggregation_strategy: str = "auto") -> tuple[str
def main() -> None: def main() -> None:
# Load global config to find active project # Load global config to find active project
""" """
[C: simulation/live_walkthrough.py:module, simulation/ping_pong.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_post_process.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] [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]
""" """
from src.paths import get_config_path from src.paths import get_config_path
config_path = get_config_path() config_path = get_config_path()
+44 -13
View File
@@ -53,12 +53,18 @@ events: EventEmitter = EventEmitter()
class ProviderError(Exception): class ProviderError(Exception):
def __init__(self, kind: str, provider: str, original: Exception) -> None: def __init__(self, kind: str, provider: str, original: Exception) -> None:
"""
[C: src/api_hooks.py:HookServerInstance.__init__, src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self.kind = kind self.kind = kind
self.provider = provider self.provider = provider
self.original = original self.original = original
super().__init__(str(original)) super().__init__(str(original))
def ui_message(self) -> str: def ui_message(self) -> str:
"""
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate]
"""
labels = { labels = {
"quota": "QUOTA EXHAUSTED", "quota": "QUOTA EXHAUSTED",
"rate_limit": "RATE LIMITED", "rate_limit": "RATE LIMITED",
@@ -74,8 +80,9 @@ class ProviderError(Exception):
def set_model_params(temp: float, max_tok: int, trunc_limit: int = 8000, top_p: float = 1.0) -> None: def set_model_params(temp: float, max_tok: int, trunc_limit: int = 8000, top_p: float = 1.0) -> None:
""" """
Sets global generation parameters like temperature and max tokens. Sets global generation parameters like temperature and max tokens.
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate] [C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate]
""" """
global _temperature, _max_tokens, _history_trunc_limit, _top_p global _temperature, _max_tokens, _history_trunc_limit, _top_p
_temperature = temp _temperature = temp
@@ -130,6 +137,7 @@ _tool_approval_modes: dict[str, str] = {}
def get_current_tier() -> Optional[str]: def get_current_tier() -> Optional[str]:
""" """
Returns the current tier from thread-local storage. Returns the current tier from thread-local storage.
[C: src/app_controller.py:AppController._on_tool_log, tests/test_ai_client_concurrency.py:intercepted_append] [C: src/app_controller.py:AppController._on_tool_log, tests/test_ai_client_concurrency.py:intercepted_append]
""" """
@@ -137,6 +145,7 @@ def get_current_tier() -> Optional[str]:
def set_current_tier(tier: Optional[str]) -> None: def set_current_tier(tier: Optional[str]) -> None:
""" """
Sets the current tier in thread-local storage. Sets the current tier in thread-local storage.
[C: src/app_controller.py:AppController._handle_request_event, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_mma_agent_focus_phase1.py:reset_tier, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2] [C: src/app_controller.py:AppController._handle_request_event, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_mma_agent_focus_phase1.py:reset_tier, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2]
""" """
@@ -144,6 +153,7 @@ def set_current_tier(tier: Optional[str]) -> None:
def get_comms_log_callback() -> Optional[Callable[[dict[str, Any]], None]]: def get_comms_log_callback() -> Optional[Callable[[dict[str, Any]], None]]:
""" """
Returns the comms log callback (thread-local with global fallback). Returns the comms log callback (thread-local with global fallback).
[C: src/multi_agent_conductor.py:run_worker_lifecycle] [C: src/multi_agent_conductor.py:run_worker_lifecycle]
""" """
@@ -153,6 +163,7 @@ def get_comms_log_callback() -> Optional[Callable[[dict[str, Any]], None]]:
def set_comms_log_callback(cb: Optional[Callable[[dict[str, Any]], None]]) -> None: def set_comms_log_callback(cb: Optional[Callable[[dict[str, Any]], None]]) -> None:
""" """
Sets the comms log callback (both global and thread-local). Sets the comms log callback (both global and thread-local).
[C: src/app_controller.py:AppController._init_ai_and_hooks, src/multi_agent_conductor.py:run_worker_lifecycle] [C: src/app_controller.py:AppController._init_ai_and_hooks, src/multi_agent_conductor.py:run_worker_lifecycle]
""" """
@@ -196,29 +207,30 @@ _project_context_marker: str = ""
def set_custom_system_prompt(prompt: str) -> None: def set_custom_system_prompt(prompt: str) -> None:
""" """
Sets a custom system prompt to be combined with the default instructions. Sets a custom system prompt to be combined with the default instructions.
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp] [C: simulation/user_agent.py:UserSimAgent.generate_response, src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp]
""" """
global _custom_system_prompt global _custom_system_prompt
_custom_system_prompt = prompt _custom_system_prompt = prompt
def set_base_system_prompt(prompt: str) -> None: def set_base_system_prompt(prompt: str) -> None:
""" """
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_get_combined_respects_use_default, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_set_base_overrides_when_default_false] [C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_get_combined_respects_use_default, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_set_base_overrides_when_default_false]
""" """
global _base_system_prompt_override global _base_system_prompt_override
_base_system_prompt_override = prompt _base_system_prompt_override = prompt
def set_use_default_base_prompt(use_default: bool) -> None: def set_use_default_base_prompt(use_default: bool) -> None:
""" """
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_get_combined_respects_use_default, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_set_base_overrides_when_default_false] [C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.setUp, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_get_combined_respects_use_default, tests/test_system_prompt_exposure.py:TestSystemPromptExposure.test_ai_client_set_base_overrides_when_default_false]
""" """
global _use_default_base_system_prompt global _use_default_base_system_prompt
_use_default_base_system_prompt = use_default _use_default_base_system_prompt = use_default
def set_project_context_marker(marker: str) -> None: def set_project_context_marker(marker: str) -> None:
""" """
[C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate] [C: src/app_controller.py:AppController._do_generate, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate]
""" """
global _project_context_marker global _project_context_marker
_project_context_marker = marker _project_context_marker = marker
@@ -297,7 +309,7 @@ def get_credentials_path() -> Path:
def _load_credentials() -> dict[str, Any]: def _load_credentials() -> dict[str, Any]:
""" """
[C: tests/test_deepseek_infra.py:test_credentials_error_mentions_deepseek, tests/test_minimax_provider.py:test_minimax_credentials_template] [C: src/ai_server.py:_send_anthropic, src/ai_server.py:_send_deepseek, src/ai_server.py:_send_gemini, src/ai_server.py:_send_minimax, src/ai_server.py:handle_command, tests/test_deepseek_infra.py:test_credentials_error_mentions_deepseek, tests/test_minimax_provider.py:test_minimax_credentials_template]
""" """
cred_path = get_credentials_path() cred_path = get_credentials_path()
try: try:
@@ -433,6 +445,7 @@ def _classify_minimax_error(exc: Exception) -> ProviderError:
def set_provider(provider: str, model: str) -> None: def set_provider(provider: str, model: str) -> None:
""" """
Updates the active LLM provider and model name. Updates the active LLM provider and model name.
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.do_fetch, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_model_selection, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_minimax_provider.py:test_minimax_default_model, tests/test_minimax_provider.py:test_minimax_model_selection, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_rag_integration.py:test_rag_integration, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script, tests/test_token_usage.py:test_token_usage_tracking] [C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.do_fetch, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_model_selection, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_minimax_provider.py:test_minimax_default_model, tests/test_minimax_provider.py:test_minimax_model_selection, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_rag_integration.py:test_rag_integration, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script, tests/test_token_usage.py:test_token_usage_tracking]
""" """
@@ -459,6 +472,7 @@ def set_provider(provider: str, model: str) -> None:
def get_provider() -> str: def get_provider() -> str:
""" """
Returns the current active provider name. Returns the current active provider name.
[C: src/multi_agent_conductor.py:run_worker_lifecycle] [C: src/multi_agent_conductor.py:run_worker_lifecycle]
""" """
@@ -466,6 +480,7 @@ def get_provider() -> str:
def cleanup() -> None: def cleanup() -> None:
""" """
Performs cleanup operations like deleting server-side Gemini caches. Performs cleanup operations like deleting server-side Gemini caches.
[C: src/app_controller.py:AppController.clear_cache, src/app_controller.py:AppController.shutdown, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking_cleanup, tests/test_log_registry.py:TestLogRegistry.tearDown, tests/test_project_serialization.py:TestProjectSerialization.tearDown] [C: src/app_controller.py:AppController.clear_cache, src/app_controller.py:AppController.shutdown, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking_cleanup, tests/test_log_registry.py:TestLogRegistry.tearDown, tests/test_project_serialization.py:TestProjectSerialization.tearDown]
""" """
@@ -479,8 +494,9 @@ def cleanup() -> None:
def reset_session() -> None: def reset_session() -> None:
""" """
Clears conversation history and resets provider-specific session state. Clears conversation history and resets provider-specific session state.
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_minimax_provider.py:test_minimax_history_bleed_stats, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking] [C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking]
""" """
global _gemini_client, _gemini_chat, _gemini_cache global _gemini_client, _gemini_chat, _gemini_cache
global _gemini_cache_md_hash, _gemini_cache_created_at, _gemini_cached_file_paths global _gemini_cache_md_hash, _gemini_cache_created_at, _gemini_cached_file_paths
@@ -546,8 +562,9 @@ _agent_tools: dict[str, bool] = {}
def set_agent_tools(tools: dict[str, bool]) -> None: def set_agent_tools(tools: dict[str, bool]) -> None:
""" """
Configures which tools are enabled for the AI agent. Configures which tools are enabled for the AI agent.
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, tests/test_agent_tools_wiring.py:test_build_anthropic_tools_conversion, tests/test_agent_tools_wiring.py:test_set_agent_tools, tests/test_tool_access_exclusion.py:test_build_anthropic_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_build_deepseek_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_gemini_tool_declaration_excludes_disabled, tests/test_tool_access_exclusion.py:test_set_agent_tools_clears_caches] [C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, tests/test_agent_tools_wiring.py:test_build_anthropic_tools_conversion, tests/test_agent_tools_wiring.py:test_set_agent_tools, tests/test_tool_access_exclusion.py:test_build_anthropic_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_build_deepseek_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_gemini_tool_declaration_excludes_disabled, tests/test_tool_access_exclusion.py:test_set_agent_tools_clears_caches]
""" """
global _agent_tools, _CACHED_ANTHROPIC_TOOLS, _CACHED_DEEPSEEK_TOOLS global _agent_tools, _CACHED_ANTHROPIC_TOOLS, _CACHED_DEEPSEEK_TOOLS
_agent_tools = tools _agent_tools = tools
@@ -556,6 +573,7 @@ def set_agent_tools(tools: dict[str, bool]) -> None:
def set_tool_preset(preset_name: Optional[str]) -> None: def set_tool_preset(preset_name: Optional[str]) -> None:
""" """
Loads a tool preset and applies it via set_agent_tools. Loads a tool preset and applies it via set_agent_tools.
[C: src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_persona_selector_panel, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_bias_integration.py:test_set_tool_preset_with_objects, tests/test_tool_preset_env.py:test_tool_preset_env_loading, tests/test_tool_preset_env.py:test_tool_preset_env_no_var, tests/test_tool_presets_execution.py:test_tool_ask_approval, tests/test_tool_presets_execution.py:test_tool_auto_approval, tests/test_tool_presets_execution.py:test_tool_rejection] [C: src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_persona_selector_panel, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_bias_integration.py:test_set_tool_preset_with_objects, tests/test_tool_preset_env.py:test_tool_preset_env_loading, tests/test_tool_preset_env.py:test_tool_preset_env_no_var, tests/test_tool_presets_execution.py:test_tool_ask_approval, tests/test_tool_presets_execution.py:test_tool_auto_approval, tests/test_tool_presets_execution.py:test_tool_rejection]
""" """
@@ -590,6 +608,7 @@ def set_tool_preset(preset_name: Optional[str]) -> None:
def set_bias_profile(profile_name: Optional[str]) -> None: def set_bias_profile(profile_name: Optional[str]) -> None:
""" """
Sets the active tool bias profile for tuning model behavior. Sets the active tool bias profile for tuning model behavior.
[C: src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_agent_tools_panel, src/gui_2.py:App._render_persona_selector_panel, src/multi_agent_conductor.py:run_worker_lifecycle] [C: src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_agent_tools_panel, src/gui_2.py:App._render_persona_selector_panel, src/multi_agent_conductor.py:run_worker_lifecycle]
""" """
@@ -733,6 +752,7 @@ async def _execute_tool_calls_concurrently(
) -> list[tuple[str, str, str, str]]: # tool_name, call_id, output, original_name ) -> list[tuple[str, str, str, str]]: # tool_name, call_id, output, original_name
""" """
Executes multiple tool calls concurrently using asyncio.gather. Executes multiple tool calls concurrently using asyncio.gather.
Returns a list of (tool_name, call_id, output, original_name). Returns a list of (tool_name, call_id, output, original_name).
[C: tests/test_async_tools.py:test_execute_tool_calls_concurrently_exception_handling, tests/test_async_tools.py:test_execute_tool_calls_concurrently_timing] [C: tests/test_async_tools.py:test_execute_tool_calls_concurrently_exception_handling, tests/test_async_tools.py:test_execute_tool_calls_concurrently_timing]
@@ -1178,6 +1198,9 @@ def _repair_anthropic_history(history: list[dict[str, Any]]) -> None:
}) })
def _send_anthropic(md_content: str, user_message: str, base_dir: str, file_items: list[dict[str, Any]] | None = None, discussion_history: str = "", pre_tool_callback: Optional[Callable[[str, str, Optional[Callable[[str], str]]], Optional[str]]] = None, qa_callback: Optional[Callable[[str], str]] = None, stream_callback: Optional[Callable[[str], None]] = None, patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str: def _send_anthropic(md_content: str, user_message: str, base_dir: str, file_items: list[dict[str, Any]] | None = None, discussion_history: str = "", pre_tool_callback: Optional[Callable[[str, str, Optional[Callable[[str], str]]], Optional[str]]] = None, qa_callback: Optional[Callable[[str], str]] = None, stream_callback: Optional[Callable[[str], None]] = None, patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
"""
[C: src/ai_server.py:_handle_send]
"""
monitor = performance_monitor.get_monitor() monitor = performance_monitor.get_monitor()
if monitor.enabled: monitor.start_component("ai_client._send_anthropic") if monitor.enabled: monitor.start_component("ai_client._send_anthropic")
try: try:
@@ -1424,7 +1447,7 @@ def _send_gemini(md_content: str, user_message: str, base_dir: str,
stream_callback: Optional[Callable[[str], None]] = None, stream_callback: Optional[Callable[[str], None]] = None,
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str: patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
""" """
[C: tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script] [C: src/ai_server.py:_handle_send, tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script]
""" """
global _gemini_chat, _gemini_cache, _gemini_cache_md_hash, _gemini_cache_created_at, _gemini_cached_file_paths global _gemini_chat, _gemini_cache, _gemini_cache_md_hash, _gemini_cache_created_at, _gemini_cached_file_paths
monitor = performance_monitor.get_monitor() monitor = performance_monitor.get_monitor()
@@ -1656,6 +1679,9 @@ def _send_gemini_cli(md_content: str, user_message: str, base_dir: str,
qa_callback: Optional[Callable[[str], str]] = None, qa_callback: Optional[Callable[[str], str]] = None,
stream_callback: Optional[Callable[[str], None]] = None, stream_callback: Optional[Callable[[str], None]] = None,
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str: patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
"""
[C: src/ai_server.py:_handle_send]
"""
global _gemini_cli_adapter global _gemini_cli_adapter
try: try:
if _gemini_cli_adapter is None: if _gemini_cli_adapter is None:
@@ -1802,6 +1828,9 @@ def _send_deepseek(md_content: str, user_message: str, base_dir: str,
qa_callback: Optional[Callable[[str], str]] = None, qa_callback: Optional[Callable[[str], str]] = None,
stream_callback: Optional[Callable[[str], None]] = None, stream_callback: Optional[Callable[[str], None]] = None,
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str: patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
"""
[C: src/ai_server.py:_handle_send]
"""
monitor = performance_monitor.get_monitor() monitor = performance_monitor.get_monitor()
if monitor.enabled: monitor.start_component("ai_client._send_deepseek") if monitor.enabled: monitor.start_component("ai_client._send_deepseek")
try: try:
@@ -2081,6 +2110,9 @@ def _send_minimax(md_content: str, user_message: str, base_dir: str,
qa_callback: Optional[Callable[[str], str]] = None, qa_callback: Optional[Callable[[str], str]] = None,
stream_callback: Optional[Callable[[str], None]] = None, stream_callback: Optional[Callable[[str], None]] = None,
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str: patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
"""
[C: src/ai_server.py:_handle_send]
"""
try: try:
mcp_client.configure(file_items or [], [base_dir]) mcp_client.configure(file_items or [], [base_dir])
creds = _load_credentials() creds = _load_credentials()
@@ -2297,7 +2329,6 @@ def _send_minimax(md_content: str, user_message: str, base_dir: str,
def run_tier4_analysis(stderr: str) -> str: def run_tier4_analysis(stderr: str) -> str:
""" """
[C: src/native_orchestrator.py:NativeOrchestrator.analyze_error]
""" """
if not stderr or not stderr.strip(): if not stderr or not stderr.strip():
return "" return ""
@@ -2346,7 +2377,7 @@ def run_tier4_patch_callback(stderr: str, base_dir: str) -> Optional[str]:
def run_tier4_patch_generation(error: str, file_context: str) -> str: def run_tier4_patch_generation(error: str, file_context: str) -> str:
""" """
[C: src/gui_2.py:App.request_patch_from_tier4, src/native_orchestrator.py:NativeOrchestrator.run_tier4_patch, 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] [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]
""" """
if not error or not error.strip(): if not error or not error.strip():
return "" return ""
@@ -2424,7 +2455,7 @@ def send(
rag_engine: Optional[Any] = None, rag_engine: Optional[Any] = None,
) -> str: ) -> str:
""" """
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/api_hooks.py:WebSocketServer._handler, src/api_hooks.py:WebSocketServer.broadcast, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:AppController.generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/native_orchestrator.py:NativeOrchestrator.execute_ticket, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_get_history_bleed_stats, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast] [C: simulation/user_agent.py:UserSimAgent.generate_response, src/api_hooks.py:WebSocketServer._handler, src/api_hooks.py:WebSocketServer.broadcast, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
""" """
monitor = performance_monitor.get_monitor() monitor = performance_monitor.get_monitor()
if monitor.enabled: monitor.start_component("ai_client.send") if monitor.enabled: monitor.start_component("ai_client.send")
@@ -2500,7 +2531,7 @@ if os.environ.get("SLOP_TOOL_PRESET"):
def run_subagent_summarization(file_path: str, content: str, is_code: bool, outline: str) -> str: def run_subagent_summarization(file_path: str, content: str, is_code: bool, outline: str) -> str:
""" """
Performs a stateless summarization request using a sub-agent prompt. [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] [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]
""" """
prompt_tmpl = mma_prompts.TIER4_SUMMARIZE_CODE_PROMPT if is_code else mma_prompts.TIER4_SUMMARIZE_TEXT_PROMPT prompt_tmpl = mma_prompts.TIER4_SUMMARIZE_CODE_PROMPT if is_code else mma_prompts.TIER4_SUMMARIZE_TEXT_PROMPT
prompt = prompt_tmpl.format(file_path=file_path, outline=outline, content=content) prompt = prompt_tmpl.format(file_path=file_path, outline=outline, content=content)
+49 -12
View File
@@ -46,6 +46,7 @@ class ApiHookClient:
def _make_request(self, method: str, path: str, data: dict | None = None, timeout: float = 5.0) -> dict[str, Any] | None: def _make_request(self, method: str, path: str, data: dict | None = None, timeout: float = 5.0) -> dict[str, Any] | None:
""" """
Helper to make HTTP requests to the hook server. Helper to make HTTP requests to the hook server.
[C: tests/test_api_hook_client.py:test_unsupported_method_error] [C: tests/test_api_hook_client.py:test_unsupported_method_error]
""" """
@@ -71,8 +72,9 @@ class ApiHookClient:
def wait_for_server(self, timeout: int = 15) -> bool: def wait_for_server(self, timeout: int = 15) -> bool:
""" """
Polls the health endpoint until the server responds or timeout occurs. Polls the health endpoint until the server responds or timeout occurs.
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_base.py:BaseSimulation.setup, tests/smoke_status_hook.py:test_status_hook, 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_auto_switch_sim.py:test_auto_switch_sim, tests/test_conductor_api_hook_integration.py:test_conductor_integrates_api_hook_client_for_verification, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, 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: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_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_custom_callback_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_workflow.py:test_full_live_workflow, 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:test_mma_step_mode_approval_flow, 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_preset_windows_layout.py:test_api_hook_under_load, tests/test_preset_windows_layout.py:test_preset_windows_opening, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_tool_management_layout.py:test_tool_management_gettable_fields, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout] [C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_base.py:BaseSimulation.setup, tests/smoke_status_hook.py:test_status_hook, 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_auto_switch_sim.py:test_auto_switch_sim, tests/test_conductor_api_hook_integration.py:test_conductor_integrates_api_hook_client_for_verification, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, 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: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_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_custom_callback_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_workflow.py:test_full_live_workflow, 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:test_mma_step_mode_approval_flow, 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_phase6_simulation.py:test_ast_inspector_modal_opens, tests/test_phase6_simulation.py:test_batch_operations_shift_click, tests/test_phase6_simulation.py:test_slice_editor_add_remove, tests/test_preset_windows_layout.py:test_api_hook_under_load, tests/test_preset_windows_layout.py:test_preset_windows_opening, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_tool_management_layout.py:test_tool_management_gettable_fields, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, 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_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
""" """
start = time.time() start = time.time()
while time.time() - start < timeout: while time.time() - start < timeout:
@@ -84,8 +86,9 @@ class ApiHookClient:
def get_status(self) -> dict[str, Any]: def get_status(self) -> dict[str, Any]:
""" """
Checks the health of the hook server. Checks the health of the hook server.
[C: tests/test_api_hook_client.py:test_get_status_success, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_hooks.py:test_live_hook_server_responses, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_preset_windows_layout.py:make_request, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls] [C: tests/test_api_hook_client.py:test_get_status_success, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_hooks.py:test_live_hook_server_responses, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_phase6_simulation.py:test_ast_inspector_modal_opens, tests/test_phase6_simulation.py:test_batch_operations_shift_click, tests/test_phase6_simulation.py:test_slice_editor_add_remove, tests/test_preset_windows_layout.py:make_request, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls]
""" """
res = self._make_request('GET', '/status') res = self._make_request('GET', '/status')
if res is None: if res is None:
@@ -96,6 +99,7 @@ class ApiHookClient:
def post_project(self, project_data: dict) -> dict[str, Any]: def post_project(self, project_data: dict) -> dict[str, Any]:
""" """
Updates the current project configuration. Updates the current project configuration.
[C: simulation/sim_context.py:ContextSimulation.run] [C: simulation/sim_context.py:ContextSimulation.run]
""" """
@@ -103,6 +107,7 @@ class ApiHookClient:
def get_project(self) -> dict[str, Any]: def get_project(self) -> dict[str, Any]:
""" """
Retrieves the current project state. Retrieves the current project state.
[C: simulation/sim_context.py:ContextSimulation.run, tests/test_api_hook_client.py:test_get_project_success, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_workflow.py:test_full_live_workflow] [C: simulation/sim_context.py:ContextSimulation.run, tests/test_api_hook_client.py:test_get_project_success, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_hooks.py:test_live_hook_server_responses, tests/test_live_workflow.py:test_full_live_workflow]
""" """
@@ -110,6 +115,7 @@ class ApiHookClient:
def get_session(self) -> dict[str, Any]: def get_session(self) -> dict[str, Any]:
""" """
Retrieves the current discussion session history. Retrieves the current discussion session history.
[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] [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]
""" """
@@ -117,6 +123,7 @@ class ApiHookClient:
def post_session(self, session_entries: list[dict]) -> dict[str, Any]: def post_session(self, session_entries: list[dict]) -> dict[str, Any]:
""" """
Updates the session history. Updates the session history.
[C: tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_live_workflow.py:test_full_live_workflow] [C: tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_live_workflow.py:test_full_live_workflow]
""" """
@@ -129,6 +136,7 @@ class ApiHookClient:
def clear_events(self) -> list[dict[str, Any]]: def clear_events(self) -> list[dict[str, Any]]:
""" """
Retrieves and clears the event queue. Retrieves and clears the event queue.
[C: simulation/sim_base.py:BaseSimulation.setup] [C: simulation/sim_base.py:BaseSimulation.setup]
""" """
@@ -150,34 +158,39 @@ class ApiHookClient:
def post_gui(self, payload: dict) -> dict[str, Any]: def post_gui(self, payload: dict) -> dict[str, Any]:
""" """
Pushes an event to the GUI's AsyncEventQueue via the /api/gui endpoint. Pushes an event to the GUI's AsyncEventQueue via the /api/gui endpoint.
[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, tests/test_visual_mma.py:test_visual_mma_components] [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 self._make_request('POST', '/api/gui', data=payload) or {} return self._make_request('POST', '/api/gui', data=payload) or {}
def push_event(self, action: str, payload: dict) -> dict[str, Any]: def push_event(self, action: str, payload: dict) -> dict[str, Any]:
""" """
Convenience to push a GUI task. Convenience to push a GUI task.
[C: tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_auto_switch_sim.py:trigger_tier, 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_context_presets.py:test_gui_context_preset_save_load, tests/test_gui_text_viewer.py:test_text_viewer_state_update, 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_preset_windows_layout.py:test_preset_windows_opening, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout] [C: tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_auto_switch_sim.py:trigger_tier, 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_context_presets.py:test_gui_context_preset_save_load, tests/test_gui_text_viewer.py:test_text_viewer_state_update, 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_preset_windows_layout.py:test_preset_windows_opening, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
""" """
return self.post_gui({"action": action, **payload}) return self.post_gui({"action": action, **payload})
def click(self, item: str, user_data: Any = None) -> dict[str, Any]: def click(self, item: str, user_data: Any = None) -> dict[str, Any]:
""" """
Simulates a button click. Simulates a button click.
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_base.py:BaseSimulation.setup, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.load_prior_log, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.setup_new_project, simulation/workflow_sim.py:WorkflowSimulator.truncate_history, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_live_workflow.py:test_full_live_workflow, 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:test_mma_step_mode_approval_flow, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_mma_v2.py:_drain_approvals, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout] [C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_base.py:BaseSimulation.setup, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.load_prior_log, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.setup_new_project, simulation/workflow_sim.py:WorkflowSimulator.truncate_history, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_live_workflow.py:test_full_live_workflow, 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:test_mma_step_mode_approval_flow, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, 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_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:_drain_approvals, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
""" """
return self.post_gui({"action": "click", "item": item, "user_data": user_data}) return self.post_gui({"action": "click", "item": item, "user_data": user_data})
def set_value(self, item: str, value: Any) -> dict[str, Any]: def set_value(self, item: str, value: Any) -> dict[str, Any]:
""" """
Sets the value of a GUI widget. Sets the value of a GUI widget.
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_ai_settings.py:AISettingsSimulation.run, simulation/sim_base.py:BaseSimulation.setup, simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.setup_new_project, simulation/workflow_sim.py:WorkflowSimulator.truncate_history, tests/smoke_status_hook.py:test_status_hook, tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, 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_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_workflow.py:test_full_live_workflow, 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:test_mma_step_mode_approval_flow, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout] [C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_ai_settings.py:AISettingsSimulation.run, simulation/sim_base.py:BaseSimulation.setup, simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.setup_new_project, simulation/workflow_sim.py:WorkflowSimulator.truncate_history, tests/smoke_status_hook.py:test_status_hook, tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, 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_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_workflow.py:test_full_live_workflow, 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:test_mma_step_mode_approval_flow, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout, tests/test_visual_mma.py:test_visual_mma_components, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration, tests/test_z_negative_flows.py:test_mock_error_result, tests/test_z_negative_flows.py:test_mock_malformed_json, tests/test_z_negative_flows.py:test_mock_timeout]
""" """
return self.post_gui({"action": "set_value", "item": item, "value": value}) return self.post_gui({"action": "set_value", "item": item, "value": value})
def select_tab(self, item: str, value: str) -> dict[str, Any]: def select_tab(self, item: str, value: str) -> dict[str, Any]:
""" """
Selects a specific tab in a tab bar. Selects a specific tab in a tab bar.
[C: simulation/live_walkthrough.py:main, tests/test_api_hook_extensions.py:test_select_tab_integration] [C: simulation/live_walkthrough.py:main, tests/test_api_hook_extensions.py:test_select_tab_integration]
""" """
@@ -185,6 +198,7 @@ class ApiHookClient:
def select_list_item(self, item: str, value: str) -> dict[str, Any]: def select_list_item(self, item: str, value: str) -> dict[str, Any]:
""" """
Selects an item in a listbox or combo. Selects an item in a listbox or combo.
[C: simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.switch_discussion, tests/test_api_hook_extensions.py:test_select_list_item_integration, tests/test_live_workflow.py:test_full_live_workflow] [C: simulation/workflow_sim.py:WorkflowSimulator.create_discussion, simulation/workflow_sim.py:WorkflowSimulator.switch_discussion, tests/test_api_hook_extensions.py:test_select_list_item_integration, tests/test_live_workflow.py:test_full_live_workflow]
""" """
@@ -192,27 +206,33 @@ class ApiHookClient:
def drag(self, src_item: str, dst_item: str) -> dict[str, Any]: def drag(self, src_item: str, dst_item: str) -> dict[str, Any]:
""" """
Simulates a drag and drop operation. Simulates a drag and drop operation.
[C: tests/test_api_hook_client.py:test_drag_success]
""" """
return self.push_event("drag", {"src_item": src_item, "dst_item": dst_item}) return self.push_event("drag", {"src_item": src_item, "dst_item": dst_item})
def right_click(self, item: str) -> dict[str, Any]: def right_click(self, item: str) -> dict[str, Any]:
""" """
Simulates a right-click on an item. Simulates a right-click on an item.
[C: tests/test_api_hook_client.py:test_right_click_success]
""" """
return self.push_event("right_click", {"item": item}) return self.push_event("right_click", {"item": item})
def get_gui_state(self) -> dict[str, Any]: def get_gui_state(self) -> dict[str, Any]:
""" """
Returns the full GUI state available via the hook API. Returns the full GUI state available via the hook API.
[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] [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 self._make_request('GET', '/api/gui/state') or {} return self._make_request('GET', '/api/gui/state') or {}
def get_value(self, item: str) -> Any: def get_value(self, item: str) -> Any:
""" """
Gets the value of a GUI item via its mapped field. Gets the value of a GUI item via its mapped field.
[C: simulation/sim_ai_settings.py:AISettingsSimulation.run, simulation/sim_base.py:BaseSimulation.get_value, simulation/sim_base.py:BaseSimulation.setup, simulation/sim_base.py:BaseSimulation.wait_for_element, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/smoke_status_hook.py:test_status_hook, tests/smoke_status_hook.py:wait_for_value, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_visual_mma.py:test_visual_mma_components, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration] [C: simulation/sim_ai_settings.py:AISettingsSimulation.run, simulation/sim_base.py:BaseSimulation.get_value, simulation/sim_base.py:BaseSimulation.setup, simulation/sim_base.py:BaseSimulation.wait_for_element, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, tests/smoke_status_hook.py:test_status_hook, tests/smoke_status_hook.py:wait_for_value, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_deepseek_infra.py:test_gui_provider_list_via_hooks, tests/test_extended_sims.py:test_ai_settings_sim_live, tests/test_gui2_parity.py:test_gui2_click_hook_works, tests/test_gui2_parity.py:test_gui2_set_value_hook_works, 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_rag_visual_sim.py:test_rag_full_lifecycle_sim, tests/test_rag_visual_sim.py:test_rag_settings_persistence_sim, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_system_prompt_sim.py:test_system_prompt_sim, tests/test_undo_redo_sim.py:test_undo_redo_context_mutation, tests/test_undo_redo_sim.py:test_undo_redo_discussion_mutation, tests/test_undo_redo_sim.py:test_undo_redo_lifecycle, tests/test_workspace_profiles_sim.py:test_workspace_profiles_restoration]
""" """
# Try state endpoint first (new preferred way) # Try state endpoint first (new preferred way)
state = self.get_gui_state() state = self.get_gui_state()
@@ -235,6 +255,7 @@ class ApiHookClient:
def get_text_value(self, item_tag: str) -> str | None: def get_text_value(self, item_tag: str) -> str | None:
""" """
Wraps get_value and returns its string representation, or None. Wraps get_value and returns its string representation, or None.
[C: tests/test_api_hook_client.py:test_get_text_value] [C: tests/test_api_hook_client.py:test_get_text_value]
""" """
@@ -243,6 +264,7 @@ class ApiHookClient:
def get_indicator_state(self, item_tag: str) -> dict[str, bool]: def get_indicator_state(self, item_tag: str) -> dict[str, bool]:
""" """
Returns the visibility/active state of a status indicator. Returns the visibility/active state of a status indicator.
[C: simulation/live_walkthrough.py:main, tests/test_api_hook_extensions.py:test_get_indicator_state_integration, tests/test_live_workflow.py:test_full_live_workflow] [C: simulation/live_walkthrough.py:main, tests/test_api_hook_extensions.py:test_get_indicator_state_integration, tests/test_live_workflow.py:test_full_live_workflow]
""" """
@@ -251,27 +273,31 @@ class ApiHookClient:
def get_gui_diagnostics(self) -> dict[str, Any]: def get_gui_diagnostics(self) -> dict[str, Any]:
""" """
Retrieves performance and diagnostic metrics. Retrieves performance and diagnostic metrics.
[C: tests/test_api_hook_client.py:test_get_performance_success, tests/test_hooks.py:test_live_hook_server_responses, tests/test_selectable_ui.py:test_selectable_label_stability] [C: tests/test_api_hook_client.py:test_get_performance_success, tests/test_hooks.py:test_live_hook_server_responses, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing]
""" """
return self._make_request('GET', '/api/gui/diagnostics') or {} return self._make_request('GET', '/api/gui/diagnostics') or {}
def get_performance(self) -> dict[str, Any]: def get_performance(self) -> dict[str, Any]:
""" """
Retrieves performance metrics from the dedicated endpoint. Retrieves performance metrics from the dedicated endpoint.
[C: tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_gui_performance_requirements.py:test_idle_performance_requirements, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing] [C: tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_gui_performance_requirements.py:test_idle_performance_requirements, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_selectable_ui.py:test_selectable_label_stability]
""" """
return self._make_request('GET', '/api/performance') or {} return self._make_request('GET', '/api/performance') or {}
def get_mma_status(self) -> dict[str, Any]: def get_mma_status(self) -> dict[str, Any]:
""" """
Retrieves the dedicated MMA engine status. Retrieves the dedicated MMA engine status.
[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_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] [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 self._make_request('GET', '/api/gui/mma_status') or {} return self._make_request('GET', '/api/gui/mma_status') or {}
def get_mma_workers(self) -> dict[str, Any]: def get_mma_workers(self) -> dict[str, Any]:
""" """
Retrieves status for all active MMA workers. Retrieves status for all active MMA workers.
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:_poll_mma_workers] [C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:_poll_mma_workers]
""" """
@@ -279,6 +305,7 @@ class ApiHookClient:
def get_context_state(self) -> dict[str, Any]: def get_context_state(self) -> dict[str, Any]:
""" """
Retrieves the current file and screenshot context state. Retrieves the current file and screenshot context state.
[C: tests/test_gui_context_presets.py:test_gui_context_preset_save_load] [C: tests/test_gui_context_presets.py:test_gui_context_preset_save_load]
""" """
@@ -294,6 +321,7 @@ class ApiHookClient:
def get_node_status(self, node_id: str) -> dict[str, Any]: def get_node_status(self, node_id: str) -> dict[str, Any]:
""" """
Retrieves status for a specific node in the MMA DAG. Retrieves status for a specific node in the MMA DAG.
[C: tests/test_api_hook_client.py:test_get_node_status] [C: tests/test_api_hook_client.py:test_get_node_status]
""" """
@@ -302,6 +330,7 @@ class ApiHookClient:
def request_confirmation(self, tool_name: str, args: dict) -> bool | None: def request_confirmation(self, tool_name: str, args: dict) -> bool | None:
""" """
Pushes a manual confirmation request and waits for response. Pushes a manual confirmation request and waits for response.
Blocks for up to 60 seconds. Blocks for up to 60 seconds.
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_sync_hooks.py:test_api_ask_client_error, tests/test_sync_hooks.py:test_api_ask_client_method, tests/test_sync_hooks.py:test_api_ask_client_rejection] [C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_sync_hooks.py:test_api_ask_client_error, tests/test_sync_hooks.py:test_api_ask_client_method, tests/test_sync_hooks.py:test_api_ask_client_rejection]
@@ -314,8 +343,9 @@ class ApiHookClient:
def reset_session(self) -> None: def reset_session(self) -> None:
""" """
Resets the current session via button click. Resets the current session via button click.
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_minimax_provider.py:test_minimax_history_bleed_stats, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking] [C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking]
""" """
self.click("btn_reset") self.click("btn_reset")
@@ -328,6 +358,7 @@ class ApiHookClient:
def apply_patch(self) -> dict[str, Any]: def apply_patch(self) -> dict[str, Any]:
""" """
Applies the pending patch. Applies the pending patch.
[C: tests/test_patch_modal.py:test_apply_callback] [C: tests/test_patch_modal.py:test_apply_callback]
""" """
@@ -335,6 +366,7 @@ class ApiHookClient:
def reject_patch(self) -> dict[str, Any]: def reject_patch(self) -> dict[str, Any]:
""" """
Rejects the pending patch. Rejects the pending patch.
[C: tests/test_patch_modal.py:test_reject_callback, tests/test_patch_modal.py:test_reject_patch] [C: tests/test_patch_modal.py:test_reject_callback, tests/test_patch_modal.py:test_reject_patch]
""" """
@@ -346,6 +378,7 @@ class ApiHookClient:
def spawn_mma_worker(self, data: dict) -> dict: def spawn_mma_worker(self, data: dict) -> dict:
""" """
Spawns a new MMA worker with the provided configuration. Spawns a new MMA worker with the provided configuration.
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation] [C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation]
""" """
@@ -357,6 +390,7 @@ class ApiHookClient:
def pause_mma_pipeline(self) -> dict: def pause_mma_pipeline(self) -> dict:
""" """
Pauses the MMA execution pipeline. Pauses the MMA execution pipeline.
[C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow] [C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow]
""" """
@@ -368,6 +402,7 @@ class ApiHookClient:
def inject_context(self, data: dict) -> dict: def inject_context(self, data: dict) -> dict:
""" """
Injects custom file context into the application. Injects custom file context into the application.
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation] [C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation]
""" """
@@ -375,6 +410,7 @@ class ApiHookClient:
def mutate_mma_dag(self, data: dict) -> dict: def mutate_mma_dag(self, data: dict) -> dict:
""" """
Mutates the MMA DAG (Directed Acyclic Graph) structure. Mutates the MMA DAG (Directed Acyclic Graph) structure.
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation] [C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation]
""" """
@@ -382,6 +418,7 @@ class ApiHookClient:
def approve_mma_ticket(self, ticket_id: str) -> dict: def approve_mma_ticket(self, ticket_id: str) -> dict:
""" """
Manually approves a specific ticket for execution in Step Mode. Manually approves a specific ticket for execution in Step Mode.
[C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow] [C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow]
""" """
+4 -3
View File
@@ -70,6 +70,7 @@ class HookServerInstance(ThreadingHTTPServer):
"""Custom HTTPServer that carries a reference to the main App instance.""" """Custom HTTPServer that carries a reference to the main App instance."""
def __init__(self, server_address: tuple[str, int], RequestHandlerClass: type, app: Any) -> None: def __init__(self, server_address: tuple[str, int], RequestHandlerClass: type, app: Any) -> None:
""" """
Initializes the server instance with an app reference. Initializes the server instance with an app reference.
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__] [C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
""" """
@@ -682,7 +683,7 @@ class HookServer:
def start(self) -> None: def start(self) -> None:
""" """
[C: src/app_controller.py:AppController._cb_accept_tracks, src/app_controller.py:AppController._cb_plan_epic, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._fetch_models, src/app_controller.py:AppController._handle_approve_ask, src/app_controller.py:AppController._handle_generate_send, src/app_controller.py:AppController._handle_md_only, src/app_controller.py:AppController._handle_reject_ask, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._prune_old_logs, src/app_controller.py:AppController._rebuild_rag_index, src/app_controller.py:AppController._run_event_loop, src/app_controller.py:AppController._start_track_logic, src/app_controller.py:AppController.cb_prune_logs, src/app_controller.py:AppController.start_services, src/gui_2.py:App._render_discussion_panel, src/mcp_client.py:ExternalMCPManager.add_server, src/multi_agent_conductor.py:WorkerPool.spawn, src/performance_monitor.py:PerformanceMonitor.__init__, tests/test_ai_client_concurrency.py:test_ai_client_tier_isolation, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread, tests/test_conductor_engine_v2.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast] [C: src/app_controller.py:AppController._cb_accept_tracks, src/app_controller.py:AppController._cb_plan_epic, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._fetch_models, src/app_controller.py:AppController._handle_approve_ask, src/app_controller.py:AppController._handle_generate_send, src/app_controller.py:AppController._handle_md_only, src/app_controller.py:AppController._handle_reject_ask, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._prune_old_logs, src/app_controller.py:AppController._rebuild_rag_index, src/app_controller.py:AppController._run_event_loop, src/app_controller.py:AppController._start_track_logic, src/app_controller.py:AppController.cb_prune_logs, src/app_controller.py:AppController.init_state, src/app_controller.py:AppController.start_services, src/gui_2.py:App._render_discussion_entry_read_mode, src/gui_2.py:App._update_context_file_stats, src/mcp_client.py:ExternalMCPManager.add_server, src/multi_agent_conductor.py:WorkerPool.spawn, src/performance_monitor.py:PerformanceMonitor.__init__, tests/test_ai_client_concurrency.py:test_ai_client_tier_isolation, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread, tests/test_conductor_engine_v2.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
""" """
if self.thread and self.thread.is_alive(): if self.thread and self.thread.is_alive():
return return
@@ -760,7 +761,7 @@ class WebSocketServer:
self._stop_event = asyncio.Event() self._stop_event = asyncio.Event()
async def main(): async def main():
""" """
[C: simulation/live_walkthrough.py:module, simulation/ping_pong.py:module, 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_post_process.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] [C: simulation/live_walkthrough.py:module, simulation/ping_pong.py:module, 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]
""" """
async with serve(self._handler, "127.0.0.1", self.port) as server: async with serve(self._handler, "127.0.0.1", self.port) as server:
self.server = server self.server = server
@@ -769,7 +770,7 @@ class WebSocketServer:
def start(self) -> None: def start(self) -> None:
""" """
[C: src/app_controller.py:AppController._cb_accept_tracks, src/app_controller.py:AppController._cb_plan_epic, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._fetch_models, src/app_controller.py:AppController._handle_approve_ask, src/app_controller.py:AppController._handle_generate_send, src/app_controller.py:AppController._handle_md_only, src/app_controller.py:AppController._handle_reject_ask, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._prune_old_logs, src/app_controller.py:AppController._rebuild_rag_index, src/app_controller.py:AppController._run_event_loop, src/app_controller.py:AppController._start_track_logic, src/app_controller.py:AppController.cb_prune_logs, src/app_controller.py:AppController.start_services, src/gui_2.py:App._render_discussion_panel, src/mcp_client.py:ExternalMCPManager.add_server, src/multi_agent_conductor.py:WorkerPool.spawn, src/performance_monitor.py:PerformanceMonitor.__init__, tests/test_ai_client_concurrency.py:test_ai_client_tier_isolation, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread, tests/test_conductor_engine_v2.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast] [C: src/app_controller.py:AppController._cb_accept_tracks, src/app_controller.py:AppController._cb_plan_epic, src/app_controller.py:AppController._cb_start_track, src/app_controller.py:AppController._fetch_models, src/app_controller.py:AppController._handle_approve_ask, src/app_controller.py:AppController._handle_generate_send, src/app_controller.py:AppController._handle_md_only, src/app_controller.py:AppController._handle_reject_ask, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController._process_event_queue, src/app_controller.py:AppController._prune_old_logs, src/app_controller.py:AppController._rebuild_rag_index, src/app_controller.py:AppController._run_event_loop, src/app_controller.py:AppController._start_track_logic, src/app_controller.py:AppController.cb_prune_logs, src/app_controller.py:AppController.init_state, src/app_controller.py:AppController.start_services, src/gui_2.py:App._render_discussion_entry_read_mode, src/gui_2.py:App._update_context_file_stats, src/mcp_client.py:ExternalMCPManager.add_server, src/multi_agent_conductor.py:WorkerPool.spawn, src/performance_monitor.py:PerformanceMonitor.__init__, tests/test_ai_client_concurrency.py:test_ai_client_tier_isolation, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread, tests/test_conductor_engine_v2.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
""" """
if self.thread and self.thread.is_alive(): if self.thread and self.thread.is_alive():
return return
+98 -36
View File
@@ -39,6 +39,7 @@ from src.file_cache import ASTParser
def parse_symbols(text: str) -> list[str]: def parse_symbols(text: str) -> list[str]:
""" """
Finds all occurrences of '@SymbolName' in text and returns SymbolName. Finds all occurrences of '@SymbolName' in text and returns SymbolName.
SymbolName can be a function, class, or method (e.g. @MyClass, @my_func, @MyClass.my_method). SymbolName can be a function, class, or method (e.g. @MyClass, @my_func, @MyClass.my_method).
[C: tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_basic, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_edge_cases, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_methods, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_mixed, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_no_symbols] [C: tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_basic, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_edge_cases, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_methods, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_mixed, tests/test_symbol_lookup.py:TestSymbolLookup.test_parse_symbols_no_symbols]
@@ -59,7 +60,7 @@ def get_symbol_definition(symbol: str, files: list[str]) -> tuple[str, str, int]
class ConfirmDialog: class ConfirmDialog:
def __init__(self, script: str, base_dir: str) -> None: def __init__(self, script: str, base_dir: str) -> None:
""" """
[C: src/app_controller.py:ConfirmDialog.__init__] [C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
""" """
self._uid = str(uuid.uuid4()) self._uid = str(uuid.uuid4())
self._script = str(script) if script is not None else "" self._script = str(script) if script is not None else ""
@@ -70,7 +71,7 @@ class ConfirmDialog:
def wait(self) -> tuple[bool, str]: def wait(self) -> tuple[bool, str]:
""" """
[C: src/app_controller.py:ConfirmDialog.wait] [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() start_time = time.time()
with self._condition: with self._condition:
@@ -83,7 +84,7 @@ class ConfirmDialog:
class MMAApprovalDialog: class MMAApprovalDialog:
def __init__(self, ticket_id: str, payload: str) -> None: def __init__(self, ticket_id: str, payload: str) -> None:
""" """
[C: src/app_controller.py:MMAApprovalDialog.__init__] [C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
""" """
self._payload = payload self._payload = payload
self._condition = threading.Condition() self._condition = threading.Condition()
@@ -92,7 +93,7 @@ class MMAApprovalDialog:
def wait(self) -> tuple[bool, str]: def wait(self) -> tuple[bool, str]:
""" """
[C: src/app_controller.py:MMAApprovalDialog.wait] [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() start_time = time.time()
with self._condition: with self._condition:
@@ -105,7 +106,7 @@ class MMAApprovalDialog:
class MMASpawnApprovalDialog: class MMASpawnApprovalDialog:
def __init__(self, ticket_id: str, role: str, prompt: str, context_md: str) -> None: def __init__(self, ticket_id: str, role: str, prompt: str, context_md: str) -> None:
""" """
[C: src/app_controller.py:MMASpawnApprovalDialog.__init__] [C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
""" """
self._prompt = prompt self._prompt = prompt
self._context_md = context_md self._context_md = context_md
@@ -116,7 +117,7 @@ class MMASpawnApprovalDialog:
def wait(self) -> dict[str, Any]: def wait(self) -> dict[str, Any]:
""" """
[C: src/app_controller.py:MMASpawnApprovalDialog.wait] [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() start_time = time.time()
with self._condition: with self._condition:
@@ -134,6 +135,7 @@ class MMASpawnApprovalDialog:
#region: API Handlers #region: API Handlers
async def _api_get_key(controller: 'AppController', header_key: str) -> str: async def _api_get_key(controller: 'AppController', header_key: str) -> str:
""" """
Validates the API key from the request header against configuration. Validates the API key from the request header against configuration.
[SDM: src/app_controller.py:_api_get_key] [SDM: src/app_controller.py:_api_get_key]
""" """
@@ -149,6 +151,7 @@ async def _api_get_key(controller: 'AppController', header_key: str) -> str:
def _api_health(controller: 'AppController') -> dict[str, str]: def _api_health(controller: 'AppController') -> dict[str, str]:
""" """
Returns the health status of the API. Returns the health status of the API.
[SDM: src/app_controller.py:_api_health] [SDM: src/app_controller.py:_api_health]
""" """
@@ -156,6 +159,7 @@ def _api_health(controller: 'AppController') -> dict[str, str]:
def _api_get_gui_state(controller: 'AppController') -> dict[str, Any]: def _api_get_gui_state(controller: 'AppController') -> dict[str, Any]:
""" """
Returns the current GUI state for specific fields. Returns the current GUI state for specific fields.
[SDM: src/app_controller.py:_api_get_gui_state] [SDM: src/app_controller.py:_api_get_gui_state]
""" """
@@ -172,6 +176,7 @@ def _api_get_gui_state(controller: 'AppController') -> dict[str, Any]:
def _api_get_mma_status(controller: 'AppController') -> dict[str, Any]: def _api_get_mma_status(controller: 'AppController') -> dict[str, Any]:
""" """
Dedicated endpoint for MMA-related status. Dedicated endpoint for MMA-related status.
[SDM: src/app_controller.py:_api_get_mma_status] [SDM: src/app_controller.py:_api_get_mma_status]
""" """
@@ -190,6 +195,7 @@ def _api_get_mma_status(controller: 'AppController') -> dict[str, Any]:
def _api_post_gui(controller: 'AppController', req: dict) -> dict[str, str]: def _api_post_gui(controller: 'AppController', req: dict) -> dict[str, str]:
""" """
Pushes a GUI task to the event queue. Pushes a GUI task to the event queue.
[SDM: src/app_controller.py:_api_post_gui] [SDM: src/app_controller.py:_api_post_gui]
""" """
@@ -198,6 +204,7 @@ def _api_post_gui(controller: 'AppController', req: dict) -> dict[str, str]:
def _api_get_api_session(controller: 'AppController') -> dict[str, Any]: def _api_get_api_session(controller: 'AppController') -> dict[str, Any]:
""" """
Returns current discussion session entries. Returns current discussion session entries.
[SDM: src/app_controller.py:_api_get_api_session] [SDM: src/app_controller.py:_api_get_api_session]
""" """
@@ -206,6 +213,7 @@ def _api_get_api_session(controller: 'AppController') -> dict[str, Any]:
def _api_post_api_session(controller: 'AppController', req: dict) -> dict[str, str]: def _api_post_api_session(controller: 'AppController', req: dict) -> dict[str, str]:
""" """
Updates session entries. Updates session entries.
[SDM: src/app_controller.py:_api_post_api_session] [SDM: src/app_controller.py:_api_post_api_session]
""" """
@@ -216,6 +224,7 @@ def _api_post_api_session(controller: 'AppController', req: dict) -> dict[str, s
def _api_get_api_project(controller: 'AppController') -> dict[str, Any]: def _api_get_api_project(controller: 'AppController') -> dict[str, Any]:
""" """
Returns current project data. Returns current project data.
[SDM: src/app_controller.py:_api_get_api_project] [SDM: src/app_controller.py:_api_get_api_project]
""" """
@@ -223,6 +232,7 @@ def _api_get_api_project(controller: 'AppController') -> dict[str, Any]:
def _api_get_performance(controller: 'AppController') -> dict[str, Any]: def _api_get_performance(controller: 'AppController') -> dict[str, Any]:
""" """
Returns performance monitor metrics. Returns performance monitor metrics.
[SDM: src/app_controller.py:_api_get_performance] [SDM: src/app_controller.py:_api_get_performance]
""" """
@@ -230,6 +240,7 @@ def _api_get_performance(controller: 'AppController') -> dict[str, Any]:
def _api_get_diagnostics(controller: 'AppController') -> dict[str, Any]: def _api_get_diagnostics(controller: 'AppController') -> dict[str, Any]:
""" """
Alias for performance metrics. Alias for performance metrics.
[SDM: src/app_controller.py:_api_get_diagnostics] [SDM: src/app_controller.py:_api_get_diagnostics]
""" """
@@ -237,6 +248,7 @@ def _api_get_diagnostics(controller: 'AppController') -> dict[str, Any]:
def _api_status(controller: 'AppController') -> dict[str, Any]: def _api_status(controller: 'AppController') -> dict[str, Any]:
""" """
Returns the current status of the application. Returns the current status of the application.
[SDM: src/app_controller.py:_api_status] [SDM: src/app_controller.py:_api_status]
""" """
@@ -249,6 +261,7 @@ def _api_status(controller: 'AppController') -> dict[str, Any]:
def _api_generate(controller: 'AppController', req: GenerateRequest) -> dict[str, Any]: def _api_generate(controller: 'AppController', req: GenerateRequest) -> dict[str, Any]:
""" """
Triggers an AI generation request using the current project context. Triggers an AI generation request using the current project context.
[SDM: src/app_controller.py:_api_generate] [SDM: src/app_controller.py:_api_generate]
""" """
@@ -313,6 +326,7 @@ def _api_generate(controller: 'AppController', req: GenerateRequest) -> dict[str
async def _api_stream(controller: 'AppController', req: GenerateRequest) -> Any: async def _api_stream(controller: 'AppController', req: GenerateRequest) -> Any:
""" """
Placeholder for streaming AI generation responses (Not yet implemented). Placeholder for streaming AI generation responses (Not yet implemented).
[SDM: src/app_controller.py:_api_stream] [SDM: src/app_controller.py:_api_stream]
""" """
@@ -320,6 +334,7 @@ async def _api_stream(controller: 'AppController', req: GenerateRequest) -> Any:
def _api_pending_actions(controller: 'AppController') -> list[dict[str, Any]]: def _api_pending_actions(controller: 'AppController') -> list[dict[str, Any]]:
""" """
Lists all pending PowerShell scripts awaiting confirmation. Lists all pending PowerShell scripts awaiting confirmation.
[SDM: src/app_controller.py:_api_pending_actions] [SDM: src/app_controller.py:_api_pending_actions]
""" """
@@ -331,6 +346,7 @@ def _api_pending_actions(controller: 'AppController') -> list[dict[str, Any]]:
def _api_confirm_action(controller: 'AppController', action_id: str, req: ConfirmRequest) -> dict[str, str]: def _api_confirm_action(controller: 'AppController', action_id: str, req: ConfirmRequest) -> dict[str, str]:
""" """
Approves or rejects a pending action. Approves or rejects a pending action.
[SDM: src/app_controller.py:_api_confirm_action] [SDM: src/app_controller.py:_api_confirm_action]
""" """
@@ -348,6 +364,7 @@ def _api_confirm_action(controller: 'AppController', action_id: str, req: Confir
def _api_list_sessions(controller: 'AppController') -> list[str]: def _api_list_sessions(controller: 'AppController') -> list[str]:
""" """
Lists all session IDs. Lists all session IDs.
[SDM: src/app_controller.py:_api_list_sessions] [SDM: src/app_controller.py:_api_list_sessions]
""" """
@@ -358,6 +375,7 @@ def _api_list_sessions(controller: 'AppController') -> list[str]:
def _api_get_session(controller: 'AppController', session_id: str) -> dict[str, Any]: def _api_get_session(controller: 'AppController', session_id: str) -> dict[str, Any]:
""" """
Returns the content of the comms.log for a specific session. Returns the content of the comms.log for a specific session.
[SDM: src/app_controller.py:_api_get_session] [SDM: src/app_controller.py:_api_get_session]
""" """
@@ -368,6 +386,7 @@ def _api_get_session(controller: 'AppController', session_id: str) -> dict[str,
def _api_delete_session(controller: 'AppController', session_id: str) -> dict[str, str]: def _api_delete_session(controller: 'AppController', session_id: str) -> dict[str, str]:
""" """
Deletes a specific session directory. Deletes a specific session directory.
[SDM: src/app_controller.py:_api_delete_session] [SDM: src/app_controller.py:_api_delete_session]
""" """
@@ -380,6 +399,7 @@ def _api_delete_session(controller: 'AppController', session_id: str) -> dict[st
def _api_get_context(controller: 'AppController') -> dict[str, Any]: def _api_get_context(controller: 'AppController') -> dict[str, Any]:
""" """
Returns the current aggregated project context. Returns the current aggregated project context.
[SDM: src/app_controller.py:_api_get_context] [SDM: src/app_controller.py:_api_get_context]
""" """
@@ -398,6 +418,7 @@ def _api_get_context(controller: 'AppController') -> dict[str, Any]:
def _api_token_stats(controller: 'AppController') -> dict[str, Any]: def _api_token_stats(controller: 'AppController') -> dict[str, Any]:
""" """
Returns current token usage and budget statistics. Returns current token usage and budget statistics.
[SDM: src/app_controller.py:_api_token_stats] [SDM: src/app_controller.py:_api_token_stats]
""" """
@@ -618,6 +639,9 @@ def _handle_mma_spawn_approval(controller: 'AppController', task: dict):
class AutoSpawnDialog: class AutoSpawnDialog:
def __init__(self, t): self.t = t def __init__(self, t): self.t = t
def wait(self): def wait(self):
"""
[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]
"""
return {'approved': True, 'abort': False, 'prompt': self.t.get("prompt"), 'context_md': self.t.get("context_md")} return {'approved': True, 'abort': False, 'prompt': self.t.get("prompt"), 'context_md': self.t.get("context_md")}
task["dialog_container"][0] = AutoSpawnDialog(task) task["dialog_container"][0] = AutoSpawnDialog(task)
return return
@@ -707,13 +731,14 @@ def _handle_hide_patch_modal(controller: 'AppController', task: dict):
class AppController: class AppController:
""" """
The headless controller for the Manual Slop application. The headless controller for the Manual Slop application.
Owns the application state and manages background services. Owns the application state and manages background services.
""" """
def __init__(self): def __init__(self):
""" """
[C: src/app_controller.py:AppController.__init__] [C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
""" """
# --- Locks --- # --- Locks ---
self._send_thread_lock: threading.Lock = threading.Lock() self._send_thread_lock: threading.Lock = threading.Lock()
@@ -1103,8 +1128,9 @@ class AppController:
def _update_inject_preview(self) -> None: def _update_inject_preview(self) -> None:
""" """
Updates the preview content based on the selected file and injection mode. Updates the preview content based on the selected file and injection mode.
[C: src/gui_2.py:App._gui_func, tests/test_skeleton_injection.py:test_update_inject_preview_full, tests/test_skeleton_injection.py:test_update_inject_preview_skeleton, tests/test_skeleton_injection.py:test_update_inject_preview_truncation] [C: src/gui_2.py:App._render_text_viewer_window, tests/test_skeleton_injection.py:test_update_inject_preview_full, tests/test_skeleton_injection.py:test_update_inject_preview_skeleton, tests/test_skeleton_injection.py:test_update_inject_preview_truncation]
""" """
if not self._inject_file_path: if not self._inject_file_path:
self._inject_preview = "" self._inject_preview = ""
@@ -1349,8 +1375,9 @@ class AppController:
def _process_pending_gui_tasks(self) -> None: def _process_pending_gui_tasks(self) -> None:
""" """
Processes pending GUI tasks from the queue on the main render thread. Processes pending GUI tasks from the queue on the main render thread.
[C: src/gui_2.py:App._gui_func, tests/test_api_hook_extensions.py:test_app_processes_new_actions, tests/test_gui_updates.py:test_gui_updates_on_event, 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_mma_orchestration_gui.py:test_handle_ai_response_fallback, tests/test_mma_orchestration_gui.py:test_handle_ai_response_with_stream_id, tests/test_mma_orchestration_gui.py:test_process_pending_gui_tasks_mma_spawn_approval, tests/test_mma_orchestration_gui.py:test_process_pending_gui_tasks_show_track_proposal, tests/test_process_pending_gui_tasks.py:test_gcli_path_updates_adapter, tests/test_process_pending_gui_tasks.py:test_redundant_calls_in_process_pending_gui_tasks] [C: src/gui_2.py:App._render_main_interface, tests/test_api_hook_extensions.py:test_app_processes_new_actions, tests/test_gui_updates.py:test_gui_updates_on_event, 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_mma_orchestration_gui.py:test_handle_ai_response_fallback, tests/test_mma_orchestration_gui.py:test_handle_ai_response_with_stream_id, tests/test_mma_orchestration_gui.py:test_process_pending_gui_tasks_mma_spawn_approval, tests/test_mma_orchestration_gui.py:test_process_pending_gui_tasks_show_track_proposal, tests/test_process_pending_gui_tasks.py:test_gcli_path_updates_adapter, tests/test_process_pending_gui_tasks.py:test_process_pending_gui_tasks_drag, tests/test_process_pending_gui_tasks.py:test_process_pending_gui_tasks_right_click, tests/test_process_pending_gui_tasks.py:test_redundant_calls_in_process_pending_gui_tasks]
""" """
now = time.time() now = time.time()
if hasattr(self, 'event_queue') and hasattr(self.event_queue, 'websocket_server') and self.event_queue.websocket_server: if hasattr(self, 'event_queue') and hasattr(self.event_queue, 'websocket_server') and self.event_queue.websocket_server:
@@ -1377,8 +1404,9 @@ class AppController:
def _process_pending_history_adds(self) -> None: def _process_pending_history_adds(self) -> None:
""" """
Synchronizes pending history entries to the active discussion and project state. Synchronizes pending history entries to the active discussion and project state.
[C: src/gui_2.py:App._gui_func] [C: src/gui_2.py:App._render_main_interface]
""" """
with self._pending_history_adds_lock: with self._pending_history_adds_lock:
items = self._pending_history_adds[:] items = self._pending_history_adds[:]
@@ -1405,8 +1433,9 @@ class AppController:
def _process_pending_tool_calls(self) -> bool: def _process_pending_tool_calls(self) -> bool:
""" """
Drains pending tool calls into the tool log. Returns True if any were processed. Drains pending tool calls into the tool log. Returns True if any were processed.
[C: src/gui_2.py:App._gui_func] [C: src/gui_2.py:App._render_main_interface]
""" """
with self._pending_tool_calls_lock: with self._pending_tool_calls_lock:
items = self._pending_tool_calls[:] items = self._pending_tool_calls[:]
@@ -1452,8 +1481,9 @@ class AppController:
def init_state(self): def init_state(self):
""" """
Initializes the application state from configurations. Initializes the application state from configurations.
[C: src/gui_2.py:App.__init__, src/gui_2.py:App._render_paths_panel, src/gui_2.py:App._save_paths, 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_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] [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]
""" """
self.active_tickets = [] self.active_tickets = []
self.ui_separate_task_dag = False self.ui_separate_task_dag = False
@@ -1638,7 +1668,7 @@ class AppController:
def cb_load_prior_log(self, path: Optional[str] = None) -> None: def cb_load_prior_log(self, path: Optional[str] = None) -> None:
""" """
[C: src/gui_2.py:App._render_log_management] [C: src/gui_2.py:App._render_log_management, src/gui_2.py:App.cb_load_prior_log]
""" """
if not path: if not path:
return return
@@ -1822,7 +1852,7 @@ class AppController:
def cb_exit_prior_session(self): def cb_exit_prior_session(self):
""" """
[C: src/gui_2.py:App._render_comms_history_panel, src/gui_2.py:App._render_discussion_panel] [C: src/gui_2.py:App._render_comms_history_panel, src/gui_2.py:App._render_prior_session_view]
""" """
self.is_viewing_prior_session = False self.is_viewing_prior_session = False
if self._current_session_usage: if self._current_session_usage:
@@ -1942,6 +1972,7 @@ class AppController:
def start_services(self, app: Any = None): def start_services(self, app: Any = None):
""" """
Starts background threads. Starts background threads.
[C: src/gui_2.py:App.__init__] [C: src/gui_2.py:App.__init__]
""" """
@@ -1953,6 +1984,7 @@ class AppController:
def shutdown(self) -> None: def shutdown(self) -> None:
""" """
Stops background threads and cleans up resources. 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] [C: src/gui_2.py:App.run, src/gui_2.py:App.shutdown, tests/conftest.py:app_instance, tests/conftest.py:mock_app]
""" """
@@ -2056,6 +2088,7 @@ class AppController:
def _handle_request_event(self, event: events.UserRequestEvent) -> None: def _handle_request_event(self, event: events.UserRequestEvent) -> None:
""" """
Processes a UserRequestEvent by calling the AI client. 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] [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]
""" """
@@ -2380,8 +2413,10 @@ class AppController:
def create_api(self) -> FastAPI: def create_api(self) -> FastAPI:
""" """
Creates and configures the FastAPI application for headless mode. Creates and configures the FastAPI application for headless mode.
[SDM: src/app_controller.py:AppController.create_api] [SDM: src/app_controller.py:AppController.create_api]
[C: src/gui_2.py:App.run, tests/test_headless_service.py:TestHeadlessAPI.setUp]
""" """
api = FastAPI(title="Manual Slop Headless API") api = FastAPI(title="Manual Slop Headless API")
API_KEY_NAME = "X-API-KEY" API_KEY_NAME = "X-API-KEY"
@@ -2393,12 +2428,21 @@ class AppController:
return _api_health(self) return _api_health(self)
@api.get("/api/gui/state", dependencies=[Depends(get_api_key)]) @api.get("/api/gui/state", dependencies=[Depends(get_api_key)])
def get_gui_state() -> dict[str, Any]: def get_gui_state() -> dict[str, Any]:
"""
[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) return _api_get_gui_state(self)
@api.get("/api/gui/mma_status", dependencies=[Depends(get_api_key)]) @api.get("/api/gui/mma_status", dependencies=[Depends(get_api_key)])
def get_mma_status() -> dict[str, Any]: def get_mma_status() -> dict[str, Any]:
"""
[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) return _api_get_mma_status(self)
@api.post("/api/gui", dependencies=[Depends(get_api_key)]) @api.post("/api/gui", dependencies=[Depends(get_api_key)])
def post_gui(req: dict) -> dict[str, str]: 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) return _api_post_gui(self, req)
@api.get("/api/session", dependencies=[Depends(get_api_key)]) @api.get("/api/session", dependencies=[Depends(get_api_key)])
def get_api_session() -> dict[str, Any]: def get_api_session() -> dict[str, Any]:
@@ -2411,6 +2455,9 @@ class AppController:
return _api_get_api_project(self) return _api_get_api_project(self)
@api.get("/api/performance", dependencies=[Depends(get_api_key)]) @api.get("/api/performance", dependencies=[Depends(get_api_key)])
def get_performance() -> dict[str, Any]: def get_performance() -> dict[str, Any]:
"""
[C: tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_gui_performance_requirements.py:test_idle_performance_requirements, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_selectable_ui.py:test_selectable_label_stability]
"""
return _api_get_performance(self) return _api_get_performance(self)
@api.get("/api/gui/diagnostics", dependencies=[Depends(get_api_key)]) @api.get("/api/gui/diagnostics", dependencies=[Depends(get_api_key)])
def get_diagnostics() -> dict[str, Any]: def get_diagnostics() -> dict[str, Any]:
@@ -2435,12 +2482,18 @@ class AppController:
return _api_list_sessions(self) return _api_list_sessions(self)
@api.get("/api/v1/sessions/{session_id}", dependencies=[Depends(get_api_key)]) @api.get("/api/v1/sessions/{session_id}", dependencies=[Depends(get_api_key)])
def get_session(session_id: str) -> dict[str, Any]: def get_session(session_id: str) -> dict[str, Any]:
"""
[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) return _api_get_session(self, session_id)
@api.delete("/api/v1/sessions/{session_id}", dependencies=[Depends(get_api_key)]) @api.delete("/api/v1/sessions/{session_id}", dependencies=[Depends(get_api_key)])
def delete_session(session_id: str) -> dict[str, str]: def delete_session(session_id: str) -> dict[str, str]:
return _api_delete_session(self, session_id) return _api_delete_session(self, session_id)
@api.get("/api/v1/context", dependencies=[Depends(get_api_key)]) @api.get("/api/v1/context", dependencies=[Depends(get_api_key)])
def get_context() -> dict[str, Any]: def get_context() -> dict[str, Any]:
"""
[C: src/fuzzy_anchor.py:FuzzyAnchor.create_slice]
"""
return _api_get_context(self) return _api_get_context(self)
@api.get("/api/v1/token_stats", dependencies=[Depends(get_api_key)]) @api.get("/api/v1/token_stats", dependencies=[Depends(get_api_key)])
def token_stats() -> dict[str, Any]: def token_stats() -> dict[str, Any]:
@@ -2529,7 +2582,7 @@ class AppController:
def _refresh_from_project(self) -> None: def _refresh_from_project(self) -> None:
# Deserialize FileItems in files.paths # 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] [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", []) raw_paths = self.project.get("files", {}).get("paths", [])
self.files = [] self.files = []
@@ -2721,7 +2774,7 @@ class AppController:
def _cb_save_view_preset(self, name: str, f_item: models.FileItem) -> None: def _cb_save_view_preset(self, name: str, f_item: models.FileItem) -> None:
""" """
[C: src/gui_2.py:App._render_files_panel] [C: src/gui_2.py:App._render_context_files_table, tests/test_view_presets.py:test_save_view_preset]
""" """
preset = models.NamedViewPreset( preset = models.NamedViewPreset(
name=name, name=name,
@@ -2739,7 +2792,7 @@ class AppController:
def _cb_apply_view_preset(self, name: str, f_item: models.FileItem) -> None: def _cb_apply_view_preset(self, name: str, f_item: models.FileItem) -> None:
""" """
[C: src/gui_2.py:App._render_files_panel] [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) preset = next((vp for vp in self.view_presets if vp.name == name), None)
if preset: if preset:
@@ -2749,7 +2802,7 @@ class AppController:
def _cb_delete_view_preset(self, name: str) -> None: def _cb_delete_view_preset(self, name: str) -> None:
""" """
[C: src/gui_2.py:App._render_files_panel] [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.view_presets = [vp for vp in self.view_presets if vp.name != name]
self._flush_to_project() self._flush_to_project()
@@ -2757,7 +2810,7 @@ class AppController:
def _cb_load_track(self, track_id: str) -> None: def _cb_load_track(self, track_id: str) -> None:
""" """
[C: src/gui_2.py:App._render_mma_dashboard] [C: src/gui_2.py:App._render_mma_track_browser]
""" """
state = project_manager.load_track_state(track_id, self.active_project_root) state = project_manager.load_track_state(track_id, self.active_project_root)
if state: if state:
@@ -2802,7 +2855,7 @@ class AppController:
def _get_discussion_names(self) -> list[str]: def _get_discussion_names(self) -> list[str]:
""" """
[C: src/gui_2.py:App._render_discussion_panel] [C: src/gui_2.py:App._render_discussion_selector, src/gui_2.py:App._render_theme_panel]
""" """
disc_sec = self.project.get("discussion", {}) disc_sec = self.project.get("discussion", {})
discussions = disc_sec.get("discussions", {}) discussions = disc_sec.get("discussions", {})
@@ -2810,7 +2863,7 @@ class AppController:
def _switch_discussion(self, name: str) -> None: def _switch_discussion(self, name: str) -> None:
""" """
[C: src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_takes_panel] [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() self._flush_disc_entries_to_project()
disc_sec = self.project.get("discussion", {}) disc_sec = self.project.get("discussion", {})
@@ -2831,7 +2884,7 @@ class AppController:
def _flush_disc_entries_to_project(self) -> None: def _flush_disc_entries_to_project(self) -> None:
""" """
[C: src/gui_2.py:App._render_discussion_panel] [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] history_strings = [project_manager.entry_to_str(e) for e in self.disc_entries]
if self.active_track and self._track_discussion_active: if self.active_track and self._track_discussion_active:
@@ -2846,7 +2899,7 @@ class AppController:
def _create_discussion(self, name: str) -> None: def _create_discussion(self, name: str) -> None:
""" """
[C: src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_synthesis_panel, src/gui_2.py:App._render_takes_panel] [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", {}) disc_sec = self.project.setdefault("discussion", {})
discussions = disc_sec.setdefault("discussions", {}) discussions = disc_sec.setdefault("discussions", {})
@@ -2860,7 +2913,7 @@ class AppController:
def _branch_discussion(self, index: int) -> None: def _branch_discussion(self, index: int) -> None:
""" """
[C: src/gui_2.py:App._render_discussion_panel] [C: src/gui_2.py:App._render_discussion_entry]
""" """
self._flush_disc_entries_to_project() self._flush_disc_entries_to_project()
# Generate a unique branch name # Generate a unique branch name
@@ -2877,7 +2930,7 @@ class AppController:
self._switch_discussion(new_name) self._switch_discussion(new_name)
def _rename_discussion(self, old_name: str, new_name: str) -> None: def _rename_discussion(self, old_name: str, new_name: str) -> None:
""" """
[C: src/gui_2.py:App._render_discussion_panel] [C: src/gui_2.py:App._render_discussion_metadata]
""" """
disc_sec = self.project.get("discussion", {}) disc_sec = self.project.get("discussion", {})
discussions = disc_sec.get("discussions", {}) discussions = disc_sec.get("discussions", {})
@@ -2893,7 +2946,7 @@ class AppController:
def _delete_discussion(self, name: str) -> None: def _delete_discussion(self, name: str) -> None:
""" """
[C: src/gui_2.py:App._render_discussion_panel] [C: src/gui_2.py:App._render_discussion_metadata]
""" """
disc_sec = self.project.get("discussion", {}) disc_sec = self.project.get("discussion", {})
discussions = disc_sec.get("discussions", {}) discussions = disc_sec.get("discussions", {})
@@ -2909,7 +2962,7 @@ class AppController:
def _handle_mma_respond(self, approved: bool, payload: str | None = None, abort: bool = False, prompt: str | None = None, context_md: str | None = None) -> None: 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._gui_func, src/gui_2.py:App._handle_approve_mma_step, src/gui_2.py:App._handle_approve_spawn] [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: if self._pending_mma_approvals:
task = self._pending_mma_approvals.pop(0) task = self._pending_mma_approvals.pop(0)
@@ -2938,8 +2991,9 @@ class AppController:
def _handle_approve_ask(self) -> None: def _handle_approve_ask(self) -> None:
""" """
Responds with approval for a pending /api/ask request. Responds with approval for a pending /api/ask request.
[C: src/gui_2.py:App.__init__, src/gui_2.py:App._gui_func] [C: src/gui_2.py:App._handle_approve_ask, src/gui_2.py:App._render_mma_modals]
""" """
if not self._ask_request_id: return if not self._ask_request_id: return
request_id = self._ask_request_id request_id = self._ask_request_id
@@ -2960,8 +3014,9 @@ class AppController:
def _handle_reject_ask(self) -> None: def _handle_reject_ask(self) -> None:
""" """
Responds with rejection for a pending /api/ask request. Responds with rejection for a pending /api/ask request.
[C: src/gui_2.py:App._gui_func] [C: src/gui_2.py:App._render_mma_modals]
""" """
if not self._ask_request_id: return if not self._ask_request_id: return
request_id = self._ask_request_id request_id = self._ask_request_id
@@ -2982,6 +3037,7 @@ class AppController:
def _handle_reset_session(self) -> None: def _handle_reset_session(self) -> None:
""" """
Logic for resetting the AI session and GUI state. Logic for resetting the AI session and GUI state.
[C: src/gui_2.py:App._render_message_panel] [C: src/gui_2.py:App._render_message_panel]
""" """
@@ -3035,6 +3091,7 @@ class AppController:
def _handle_md_only(self) -> None: def _handle_md_only(self) -> None:
""" """
Logic for the 'MD Only' action. Logic for the 'MD Only' action.
[C: src/gui_2.py:App._render_message_panel] [C: src/gui_2.py:App._render_message_panel]
""" """
@@ -3057,6 +3114,7 @@ class AppController:
def _handle_generate_send(self) -> None: def _handle_generate_send(self) -> None:
""" """
Logic for the 'Gen + Send' action. 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] [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]
""" """
@@ -3182,7 +3240,7 @@ class AppController:
def _flush_to_project(self) -> None: def _flush_to_project(self) -> None:
""" """
[C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_projects_panel, src/gui_2.py:App._show_menus] [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 = self.project
proj.setdefault("output", {})["output_dir"] = self.ui_output_dir proj.setdefault("output", {})["output_dir"] = self.ui_output_dir
@@ -3222,7 +3280,7 @@ class AppController:
def _flush_to_config(self) -> None: def _flush_to_config(self) -> None:
""" """
[C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_panel, 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] [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"] = { self.config["ai"] = {
"provider": self.current_provider, "provider": self.current_provider,
@@ -3266,8 +3324,9 @@ class AppController:
def _do_generate(self) -> tuple[str, Path, list[dict[str, Any]], str, str]: def _do_generate(self) -> tuple[str, Path, list[dict[str, Any]], str, str]:
""" """
Returns (full_md, output_path, file_items, stable_md, discussion_text). Returns (full_md, output_path, file_items, stable_md, discussion_text).
[C: src/gui_2.py:App._show_menus, tests/test_tiered_aggregation.py:test_app_controller_do_generate_uses_persona_strategy] [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]
""" """
self._flush_to_project() self._flush_to_project()
self._flush_to_config() self._flush_to_config()
@@ -3301,7 +3360,7 @@ class AppController:
def _cb_plan_epic(self) -> None: def _cb_plan_epic(self) -> None:
""" """
[C: src/gui_2.py:App._render_mma_dashboard, tests/test_mma_orchestration_gui.py:test_cb_plan_epic_launches_thread] [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() -> None: def _bg_task() -> None:
try: try:
@@ -3540,6 +3599,7 @@ class AppController:
def kill_worker(self, worker_id: str) -> None: def kill_worker(self, worker_id: str) -> None:
""" """
Aborts a running worker. 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] [C: src/gui_2.py:App._cb_kill_ticket, tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread]
""" """
@@ -3564,6 +3624,7 @@ class AppController:
def inject_context(self, data: dict) -> None: def inject_context(self, data: dict) -> None:
""" """
Programmatic context injection. Programmatic context injection.
[C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation] [C: tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation]
""" """
@@ -3613,7 +3674,7 @@ class AppController:
def _cb_run_conductor_setup(self) -> None: def _cb_run_conductor_setup(self) -> None:
""" """
[C: src/gui_2.py:App._render_mma_dashboard, tests/test_gui_phase3.py:test_conductor_setup_scan] [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) base = paths.get_conductor_dir(project_path=self.active_project_root)
if not base.exists(): if not base.exists():
@@ -3643,7 +3704,7 @@ class AppController:
def _cb_create_track(self, name: str, desc: str, track_type: str) -> None: def _cb_create_track(self, name: str, desc: str, track_type: str) -> None:
""" """
[C: src/gui_2.py:App._render_mma_dashboard, tests/test_gui_phase3.py:test_create_track] [C: src/gui_2.py:App._render_mma_track_browser, tests/test_gui_phase3.py:test_create_track]
""" """
if not name: return if not name: return
date_suffix = datetime.now().strftime("%Y%m%d") date_suffix = datetime.now().strftime("%Y%m%d")
@@ -3671,7 +3732,7 @@ class AppController:
def _push_mma_state_update(self) -> None: def _push_mma_state_update(self) -> None:
""" """
[C: src/gui_2.py:App._cb_block_ticket, src/gui_2.py:App._cb_unblock_ticket, src/gui_2.py:App._render_mma_dashboard, src/gui_2.py:App._render_task_dag_panel, src/gui_2.py:App._render_ticket_queue, src/gui_2.py:App._reorder_ticket, src/gui_2.py:App.bulk_block, src/gui_2.py:App.bulk_execute, src/gui_2.py:App.bulk_skip, tests/test_gui_phase4.py:test_push_mma_state_update] [C: src/gui_2.py:App._cb_block_ticket, src/gui_2.py:App._cb_unblock_ticket, src/gui_2.py:App._render_mma_ticket_editor, src/gui_2.py:App._render_task_dag_panel, src/gui_2.py:App._render_ticket_queue, src/gui_2.py:App._reorder_ticket, src/gui_2.py:App.bulk_block, src/gui_2.py:App.bulk_execute, src/gui_2.py:App.bulk_skip, tests/test_gui_phase4.py:test_push_mma_state_update]
""" """
if not self.active_track: if not self.active_track:
return return
@@ -3696,6 +3757,7 @@ class AppController:
def _load_active_tickets(self) -> None: def _load_active_tickets(self) -> None:
""" """
Populates self.active_tickets based on the current execution mode. Populates self.active_tickets based on the current execution mode.
[C: tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads] [C: tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads]
""" """
+5
View File
@@ -21,6 +21,7 @@ class BeadsClient:
def init_repo(self) -> None: def init_repo(self) -> None:
""" """
Initialize the mock repository. Initialize the mock repository.
[C: tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query, tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads, tests/test_mcp_client_beads.py:test_bd_mcp_tools] [C: tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query, tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads, tests/test_mcp_client_beads.py:test_bd_mcp_tools]
""" """
@@ -30,6 +31,7 @@ class BeadsClient:
def is_initialized(self) -> bool: def is_initialized(self) -> bool:
""" """
Check if the repository is initialized. Check if the repository is initialized.
[C: src/mcp_client.py:dispatch, tests/test_beads_client.py:test_beads_init_and_query] [C: src/mcp_client.py:dispatch, tests/test_beads_client.py:test_beads_init_and_query]
""" """
@@ -37,6 +39,7 @@ class BeadsClient:
def create_bead(self, title: str, description: str) -> str: def create_bead(self, title: str, description: str) -> str:
""" """
Create a new bead and return its ID. Create a new bead and return its ID.
[C: src/mcp_client.py:dispatch, tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query, tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads] [C: src/mcp_client.py:dispatch, tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query, tests/test_gui_dag_beads.py:test_load_active_tickets_from_beads]
""" """
@@ -49,6 +52,7 @@ class BeadsClient:
def update_bead(self, bead_id: str, status: str) -> bool: def update_bead(self, bead_id: str, status: str) -> bool:
""" """
Update the status of an existing bead. Update the status of an existing bead.
[C: src/mcp_client.py:dispatch, tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query] [C: src/mcp_client.py:dispatch, tests/test_aggregate_beads.py:test_build_beads_compaction, tests/test_beads_client.py:test_beads_init_and_query]
""" """
@@ -62,6 +66,7 @@ class BeadsClient:
def list_beads(self) -> List[Bead]: def list_beads(self) -> List[Bead]:
""" """
List all beads. List all beads.
[C: src/gui_2.py:App._render_beads_tab, src/mcp_client.py:dispatch, tests/test_beads_client.py:test_beads_init_and_query] [C: src/gui_2.py:App._render_beads_tab, src/mcp_client.py:dispatch, tests/test_beads_client.py:test_beads_init_and_query]
""" """
+1 -1
View File
@@ -16,7 +16,7 @@ class BackgroundShader:
def render(self, width: float, height: float): def render(self, width: float, height: float):
""" """
[C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_panel, src/gui_2.py:App._render_heavy_text, src/gui_2.py:App._render_markdown_test, src/gui_2.py:App._render_response_panel, src/gui_2.py:App._render_snapshot_tab, src/markdown_helper.py:MarkdownRenderer._render_code_block, src/markdown_helper.py:MarkdownRenderer.render, src/markdown_helper.py:render, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render] [C: src/gui_2.py:App._gui_func, src/gui_2.py:App._render_discussion_entry_read_mode, src/gui_2.py:App._render_heavy_text, src/gui_2.py:App._render_markdown_test, src/gui_2.py:App._render_prior_session_view, src/gui_2.py:App._render_response_panel, src/gui_2.py:App._render_snapshot_tab, src/gui_2.py:App._render_text_viewer_window, src/markdown_helper.py:MarkdownRenderer._render_code_block, src/markdown_helper.py:MarkdownRenderer.render, src/markdown_helper.py:render, src/theme_2.py:render_post_fx, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
""" """
if not self.enabled or width <= 0 or height <= 0: if not self.enabled or width <= 0 or height <= 0:
return return
+3 -1
View File
@@ -42,9 +42,10 @@ from typing import Any
def generate_tickets(track_brief: str, module_skeletons: str) -> list[dict[str, Any]]: def generate_tickets(track_brief: str, module_skeletons: str) -> list[dict[str, Any]]:
""" """
Tier 2 (Tech Lead) call. Tier 2 (Tech Lead) call.
Breaks down a Track Brief and module skeletons into discrete Tier 3 Tickets. Breaks down a Track Brief and module skeletons into discrete Tier 3 Tickets.
[C: src/native_orchestrator.py:NativeOrchestrator.generate_tickets, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_failure, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_success, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_success, tests/test_orchestration_logic.py:test_generate_tickets] [C: tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_failure, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_success, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_success, tests/test_orchestration_logic.py:test_generate_tickets]
""" """
# 1. Set Tier 2 Model (Tech Lead - Flash) # 1. Set Tier 2 Model (Tech Lead - Flash)
# 2. Construct Prompt # 2. Construct Prompt
@@ -98,6 +99,7 @@ from src.models import Ticket
def topological_sort(tickets: list[dict[str, Any]]) -> list[dict[str, Any]]: def topological_sort(tickets: list[dict[str, Any]]) -> list[dict[str, Any]]:
""" """
Sorts a list of tickets based on their 'depends_on' field. Sorts a list of tickets based on their 'depends_on' field.
Raises ValueError if a circular dependency or missing internal dependency is detected. Raises ValueError if a circular dependency or missing internal dependency is detected.
[C: tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_complex, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_cycle, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_empty, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_linear, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_missing_dependency, tests/test_conductor_tech_lead.py:test_topological_sort_vlog, tests/test_dag_engine.py:test_topological_sort, tests/test_dag_engine.py:test_topological_sort_cycle, tests/test_orchestration_logic.py:test_topological_sort, tests/test_orchestration_logic.py:test_topological_sort_circular, tests/test_perf_dag.py:test_dag_edge_cases, tests/test_perf_dag.py:test_dag_performance] [C: tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_complex, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_cycle, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_empty, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_linear, tests/test_conductor_tech_lead.py:TestTopologicalSort.test_topological_sort_missing_dependency, tests/test_conductor_tech_lead.py:test_topological_sort_vlog, tests/test_dag_engine.py:test_topological_sort, tests/test_dag_engine.py:test_topological_sort_cycle, tests/test_orchestration_logic.py:test_topological_sort, tests/test_orchestration_logic.py:test_topological_sort_circular, tests/test_perf_dag.py:test_dag_edge_cases, tests/test_perf_dag.py:test_dag_performance]
+2 -1
View File
@@ -47,9 +47,10 @@ MODEL_PRICING = [
def estimate_cost(model: str, input_tokens: int, output_tokens: int) -> float: def estimate_cost(model: str, input_tokens: int, output_tokens: int) -> float:
""" """
Estimate the cost of a model call based on input and output tokens. Estimate the cost of a model call based on input and output tokens.
Returns the total cost in USD. Returns the total cost in USD.
[C: src/gui_2.py:App._render_mma_dashboard, src/gui_2.py:App._render_token_budget_panel, tests/test_cost_tracker.py:test_estimate_cost] [C: src/gui_2.py:App._render_mma_track_summary, src/gui_2.py:App._render_mma_usage_section, src/gui_2.py:App._render_token_budget_panel, tests/test_cost_tracker.py:test_estimate_cost]
""" """
if not model: if not model:
return 0.0 return 0.0
+11
View File
@@ -33,6 +33,7 @@ from src.performance_monitor import get_monitor
class TrackDAG: class TrackDAG:
""" """
Manages a Directed Acyclic Graph of implementation tickets. Manages a Directed Acyclic Graph of implementation tickets.
Provides methods for dependency resolution, cycle detection, and topological sorting. Provides methods for dependency resolution, cycle detection, and topological sorting.
""" """
@@ -40,6 +41,7 @@ class TrackDAG:
def __init__(self, tickets: List[Ticket]) -> None: def __init__(self, tickets: List[Ticket]) -> None:
""" """
Initializes the TrackDAG with a list of Ticket objects. Initializes the TrackDAG with a list of Ticket objects.
Args: Args:
tickets: A list of Ticket instances defining the graph nodes and edges. tickets: A list of Ticket instances defining the graph nodes and edges.
@@ -51,6 +53,7 @@ class TrackDAG:
def cascade_blocks(self) -> None: def cascade_blocks(self) -> None:
""" """
Transitively marks `todo` tickets as `blocked` if any dependency is `blocked`. Transitively marks `todo` tickets as `blocked` if any dependency is `blocked`.
Propagates 'blocked' status from initially blocked nodes to their dependents. Propagates 'blocked' status from initially blocked nodes to their dependents.
[C: tests/test_perf_dag.py:test_dag_performance] [C: tests/test_perf_dag.py:test_dag_performance]
@@ -88,6 +91,7 @@ class TrackDAG:
def get_ready_tasks(self) -> List[Ticket]: def get_ready_tasks(self) -> List[Ticket]:
""" """
Returns a list of tickets that are in 'todo' status and whose dependencies are all 'completed'. Returns a list of tickets that are in 'todo' status and whose dependencies are all 'completed'.
Returns: Returns:
A list of Ticket objects ready for execution. A list of Ticket objects ready for execution.
@@ -102,6 +106,7 @@ class TrackDAG:
def has_cycle(self) -> bool: def has_cycle(self) -> bool:
""" """
Performs an iterative Depth-First Search to detect cycles in the dependency graph. Performs an iterative Depth-First Search to detect cycles in the dependency graph.
Returns: Returns:
True if a cycle is detected, False otherwise. True if a cycle is detected, False otherwise.
@@ -135,6 +140,7 @@ class TrackDAG:
def topological_sort(self) -> List[str]: def topological_sort(self) -> List[str]:
""" """
Returns a list of ticket IDs in topological order (dependencies before dependents). Returns a list of ticket IDs in topological order (dependencies before dependents).
Uses Kahn's algorithm for efficient O(V+E) sorting and cycle detection. Uses Kahn's algorithm for efficient O(V+E) sorting and cycle detection.
Returns: Returns:
@@ -171,6 +177,7 @@ class TrackDAG:
class ExecutionEngine: class ExecutionEngine:
""" """
A state machine that governs the progression of tasks within a TrackDAG. A state machine that governs the progression of tasks within a TrackDAG.
Handles automatic queueing and manual task approval. Handles automatic queueing and manual task approval.
""" """
@@ -178,6 +185,7 @@ class ExecutionEngine:
def __init__(self, dag: TrackDAG, auto_queue: bool = False) -> None: def __init__(self, dag: TrackDAG, auto_queue: bool = False) -> None:
""" """
Initializes the ExecutionEngine. Initializes the ExecutionEngine.
Args: Args:
dag: The TrackDAG instance to manage. dag: The TrackDAG instance to manage.
@@ -190,6 +198,7 @@ class ExecutionEngine:
def tick(self) -> List[Ticket]: def tick(self) -> List[Ticket]:
""" """
Evaluates the DAG and returns a list of tasks that are currently 'ready' for execution. Evaluates the DAG and returns a list of tasks that are currently 'ready' for execution.
If auto_queue is enabled, tasks without 'step_mode' will be marked as 'in_progress'. If auto_queue is enabled, tasks without 'step_mode' will be marked as 'in_progress'.
Returns: Returns:
@@ -204,6 +213,7 @@ class ExecutionEngine:
def approve_task(self, task_id: str) -> None: def approve_task(self, task_id: str) -> None:
""" """
Manually transitions a task from 'todo' to 'in_progress' if its dependencies are met. Manually transitions a task from 'todo' to 'in_progress' if its dependencies are met.
Args: Args:
task_id: The ID of the task to approve. task_id: The ID of the task to approve.
@@ -216,6 +226,7 @@ class ExecutionEngine:
def update_task_status(self, task_id: str, status: str) -> None: def update_task_status(self, task_id: str, status: str) -> None:
""" """
Force-updates the status of a specific task. Force-updates the status of a specific task.
Args: Args:
task_id: The ID of the task. task_id: The ID of the task.
+1 -1
View File
@@ -45,7 +45,7 @@ def parse_hunk_header(line: str) -> Optional[tuple[int, int, int, int]]:
def parse_diff(diff_text: str) -> List[DiffFile]: def parse_diff(diff_text: str) -> List[DiffFile]:
""" """
[C: src/gui_2.py:App.request_patch_from_tier4, tests/test_diff_viewer.py:test_diff_line_classification, tests/test_diff_viewer.py:test_parse_diff_empty, tests/test_diff_viewer.py:test_parse_diff_none, tests/test_diff_viewer.py:test_parse_diff_with_context, tests/test_diff_viewer.py:test_parse_multiple_files, tests/test_diff_viewer.py:test_parse_simple_diff, tests/test_diff_viewer.py:test_render_diff_text_immediate] [C: src/gui_2.py:App.request_patch_from_tier4, tests/test_diff_viewer.py:test_diff_line_classification, tests/test_diff_viewer.py:test_parse_diff_empty, tests/test_diff_viewer.py:test_parse_diff_none, tests/test_diff_viewer.py:test_parse_diff_with_context, tests/test_diff_viewer.py:test_parse_multiple_files, tests/test_diff_viewer.py:test_parse_simple_diff]
""" """
if not diff_text or not diff_text.strip(): if not diff_text or not diff_text.strip():
return [] return []
+16 -4
View File
File diff suppressed because one or more lines are too long
+18 -1
View File
@@ -47,6 +47,7 @@ _ast_cache: Dict[str, Tuple[float, tree_sitter.Tree]] = {}
class ASTParser: class ASTParser:
""" """
Parser for extracting AST-based views of source code. Parser for extracting AST-based views of source code.
Currently supports Python. Currently supports Python.
""" """
@@ -69,6 +70,7 @@ class ASTParser:
def parse(self, code: str) -> tree_sitter.Tree: def parse(self, code: str) -> tree_sitter.Tree:
""" """
Parse the given code and return the tree-sitter Tree. Parse the given code and return the tree-sitter Tree.
[C: src/mcp_client.py:_search_file, src/mcp_client.py:derive_code_path, src/mcp_client.py:py_check_syntax, src/mcp_client.py:py_get_class_summary, src/mcp_client.py:py_get_definition, src/mcp_client.py:py_get_docstring, src/mcp_client.py:py_get_imports, src/mcp_client.py:py_get_signature, src/mcp_client.py:py_get_symbol_info, src/mcp_client.py:py_get_var_declaration, src/mcp_client.py:py_set_signature, src/mcp_client.py:py_set_var_declaration, src/mcp_client.py:py_update_definition, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/rag_engine.py:RAGEngine._chunk_code, src/summarize.py:_summarise_python, tests/test_ast_parser.py:test_ast_parser_parse, tests/test_tree_sitter_setup.py:test_tree_sitter_python_setup] [C: src/mcp_client.py:_search_file, src/mcp_client.py:derive_code_path, src/mcp_client.py:py_check_syntax, src/mcp_client.py:py_get_class_summary, src/mcp_client.py:py_get_definition, src/mcp_client.py:py_get_docstring, src/mcp_client.py:py_get_imports, src/mcp_client.py:py_get_signature, src/mcp_client.py:py_get_symbol_info, src/mcp_client.py:py_get_var_declaration, src/mcp_client.py:py_set_signature, src/mcp_client.py:py_set_var_declaration, src/mcp_client.py:py_update_definition, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/rag_engine.py:RAGEngine._chunk_code, src/summarize.py:_summarise_python, tests/test_ast_parser.py:test_ast_parser_parse, tests/test_tree_sitter_setup.py:test_tree_sitter_python_setup]
""" """
@@ -185,6 +187,7 @@ class ASTParser:
def get_skeleton(self, code: str, path: Optional[str] = None) -> str: def get_skeleton(self, code: str, path: Optional[str] = None) -> str:
""" """
Returns a skeleton of a Python file (preserving docstrings, stripping function bodies). Returns a skeleton of a Python file (preserving docstrings, stripping function bodies).
[C: src/mcp_client.py:py_get_skeleton, src/mcp_client.py:ts_c_get_skeleton, src/mcp_client.py:ts_cpp_get_skeleton, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ast_parser.py:test_ast_parser_get_skeleton_c, tests/test_ast_parser.py:test_ast_parser_get_skeleton_cpp, tests/test_ast_parser.py:test_ast_parser_get_skeleton_python, tests/test_context_pruner.py:test_ast_caching, tests/test_context_pruner.py:test_performance_large_file] [C: src/mcp_client.py:py_get_skeleton, src/mcp_client.py:ts_c_get_skeleton, src/mcp_client.py:ts_cpp_get_skeleton, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ast_parser.py:test_ast_parser_get_skeleton_c, tests/test_ast_parser.py:test_ast_parser_get_skeleton_cpp, tests/test_ast_parser.py:test_ast_parser_get_skeleton_python, tests/test_context_pruner.py:test_ast_caching, tests/test_context_pruner.py:test_performance_large_file]
""" """
@@ -238,6 +241,7 @@ class ASTParser:
def get_curated_view(self, code: str, path: Optional[str] = None) -> str: def get_curated_view(self, code: str, path: Optional[str] = None) -> str:
""" """
Returns a curated skeleton of a Python file. Returns a curated skeleton of a Python file.
Preserves function bodies if they have @core_logic decorator or # [HOT] comment. Preserves function bodies if they have @core_logic decorator or # [HOT] comment.
Otherwise strips bodies but preserves docstrings. Otherwise strips bodies but preserves docstrings.
@@ -317,6 +321,7 @@ class ASTParser:
def get_targeted_view(self, code: str, function_names: List[str], path: Optional[str] = None) -> str: def get_targeted_view(self, code: str, function_names: List[str], path: Optional[str] = None) -> str:
""" """
Returns a targeted view of the code including only the specified functions Returns a targeted view of the code including only the specified functions
and their dependencies up to depth 2. and their dependencies up to depth 2.
[C: src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ast_parser.py:test_ast_parser_get_targeted_view, tests/test_context_pruner.py:test_class_targeted_extraction, tests/test_context_pruner.py:test_targeted_extraction] [C: src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ast_parser.py:test_ast_parser_get_targeted_view, tests/test_context_pruner.py:test_class_targeted_extraction, tests/test_context_pruner.py:test_targeted_extraction]
@@ -482,6 +487,7 @@ class ASTParser:
#region: Symbol Extraction #region: Symbol Extraction
def get_definition(self, code: str, name: str, path: Optional[str] = None) -> str: def get_definition(self, code: str, name: str, path: Optional[str] = None) -> str:
""" """
Returns the full source code for a specific definition by name. Returns the full source code for a specific definition by name.
Supports 'ClassName::method' or 'method' for C++. Supports 'ClassName::method' or 'method' for C++.
[C: src/mcp_client.py:trace, src/mcp_client.py:ts_c_get_definition, src/mcp_client.py:ts_cpp_get_definition, tests/test_ast_parser.py:test_ast_parser_get_definition_c, tests/test_ast_parser.py:test_ast_parser_get_definition_cpp, tests/test_ast_parser.py:test_ast_parser_get_definition_cpp_template] [C: src/mcp_client.py:trace, src/mcp_client.py:ts_c_get_definition, src/mcp_client.py:ts_cpp_get_definition, tests/test_ast_parser.py:test_ast_parser_get_definition_c, tests/test_ast_parser.py:test_ast_parser_get_definition_cpp, tests/test_ast_parser.py:test_ast_parser_get_definition_cpp_template]
@@ -492,6 +498,9 @@ class ASTParser:
parts = re.split(r'::|\.', name) parts = re.split(r'::|\.', name)
def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]: def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]:
"""
[C: src/mcp_client.py:_search_file, src/mcp_client.py:py_find_usages, src/mcp_client.py:py_get_hierarchy, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/outline_tool.py:CodeOutliner.walk, src/summarize.py:_summarise_python]
"""
if not target_parts: if not target_parts:
return None return None
target = target_parts[0] target = target_parts[0]
@@ -578,6 +587,7 @@ class ASTParser:
def get_signature(self, code: str, name: str, path: Optional[str] = None) -> str: def get_signature(self, code: str, name: str, path: Optional[str] = None) -> str:
""" """
Returns only the signature part of a function or method. Returns only the signature part of a function or method.
For C/C++, this is the code from the start of the definition until the block start '{'. For C/C++, this is the code from the start of the definition until the block start '{'.
[C: src/mcp_client.py:ts_c_get_signature, src/mcp_client.py:ts_cpp_get_signature, tests/test_ast_parser.py:test_ast_parser_get_signature_c, tests/test_ast_parser.py:test_ast_parser_get_signature_cpp] [C: src/mcp_client.py:ts_c_get_signature, src/mcp_client.py:ts_cpp_get_signature, tests/test_ast_parser.py:test_ast_parser_get_signature_c, tests/test_ast_parser.py:test_ast_parser_get_signature_cpp]
@@ -588,6 +598,9 @@ class ASTParser:
parts = re.split(r'::|\.', name) parts = re.split(r'::|\.', name)
def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]: def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]:
"""
[C: src/mcp_client.py:_search_file, src/mcp_client.py:py_find_usages, src/mcp_client.py:py_get_hierarchy, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/outline_tool.py:CodeOutliner.walk, src/summarize.py:_summarise_python]
"""
if not target_parts: if not target_parts:
return None return None
target = target_parts[0] target = target_parts[0]
@@ -687,6 +700,7 @@ class ASTParser:
def get_code_outline(self, code: str, path: Optional[str] = None) -> str: def get_code_outline(self, code: str, path: Optional[str] = None) -> str:
""" """
Returns a hierarchical outline of the code (classes, structs, functions, methods). Returns a hierarchical outline of the code (classes, structs, functions, methods).
[C: src/mcp_client.py:ts_c_get_code_outline, src/mcp_client.py:ts_cpp_get_code_outline, tests/test_ast_parser.py:test_ast_parser_get_code_outline_c, tests/test_ast_parser.py:test_ast_parser_get_code_outline_cpp] [C: src/mcp_client.py:ts_c_get_code_outline, src/mcp_client.py:ts_cpp_get_code_outline, tests/test_ast_parser.py:test_ast_parser_get_code_outline_c, tests/test_ast_parser.py:test_ast_parser_get_code_outline_cpp]
""" """
@@ -728,6 +742,7 @@ class ASTParser:
def update_definition(self, code: str, name: str, new_content: str, path: Optional[str] = None) -> str: def update_definition(self, code: str, name: str, new_content: str, path: Optional[str] = None) -> str:
""" """
Surgically replace the definition of a class or function by name. Surgically replace the definition of a class or function by name.
[C: src/mcp_client.py:ts_c_update_definition, src/mcp_client.py:ts_cpp_update_definition, tests/test_ast_parser.py:test_ast_parser_update_definition_cpp] [C: src/mcp_client.py:ts_c_update_definition, src/mcp_client.py:ts_cpp_update_definition, tests/test_ast_parser.py:test_ast_parser_update_definition_cpp]
""" """
@@ -737,6 +752,9 @@ class ASTParser:
parts = re.split(r'::|\.', name) parts = re.split(r'::|\.', name)
def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]: def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]:
"""
[C: src/mcp_client.py:_search_file, src/mcp_client.py:py_find_usages, src/mcp_client.py:py_get_hierarchy, src/mcp_client.py:trace, src/outline_tool.py:CodeOutliner.outline, src/outline_tool.py:CodeOutliner.walk, src/summarize.py:_summarise_python]
"""
if not target_parts: if not target_parts:
return None return None
target = target_parts[0] target = target_parts[0]
@@ -830,4 +848,3 @@ def reset_client() -> None:
def get_file_id(path: Path) -> Optional[str]: def get_file_id(path: Path) -> Optional[str]:
return None return None
#endregion: Module Level Utilities #endregion: Module Level Utilities
+7 -1
View File
@@ -16,7 +16,10 @@ class FuzzyAnchor:
@classmethod @classmethod
def create_slice(cls, text: str, start_line: int, end_line: int) -> dict: def create_slice(cls, text: str, start_line: int, end_line: int) -> dict:
"""start_line and end_line are 1-based.""" """
start_line and end_line are 1-based.
[C: src/gui_2.py:App._populate_auto_slices, src/gui_2.py:App._render_text_viewer_window, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_create_slice_basic, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_anchor_mismatch_returns_none, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_exact_match, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_line_deleted_before_returns_none, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_line_inserted_before, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_multiple_lines_changed, tests/test_slice_editor_behavior.py:test_add_slice_with_annotations]
"""
lines = text.splitlines() lines = text.splitlines()
s_idx = max(0, start_line - 1) s_idx = max(0, start_line - 1)
e_idx = min(len(lines), end_line) e_idx = min(len(lines), end_line)
@@ -33,6 +36,9 @@ class FuzzyAnchor:
@classmethod @classmethod
def resolve_slice(cls, text: str, slice_data: dict) -> Optional[Tuple[int, int]]: def resolve_slice(cls, text: str, slice_data: dict) -> Optional[Tuple[int, int]]:
"""
[C: tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_anchor_mismatch_returns_none, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_exact_match, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_line_deleted_before_returns_none, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_line_inserted_before, tests/test_fuzzy_anchor.py:TestFuzzyAnchor.test_resolve_slice_multiple_lines_changed]
"""
lines = text.splitlines() lines = text.splitlines()
# 1. Try exact match # 1. Try exact match
s_idx = slice_data["start_line"] - 1 s_idx = slice_data["start_line"] - 1
+5 -1
View File
@@ -45,10 +45,12 @@ from typing import Optional, Callable, Any
class GeminiCliAdapter: class GeminiCliAdapter:
""" """
Adapter for the Gemini CLI that parses streaming JSON output. Adapter for the Gemini CLI that parses streaming JSON output.
""" """
def __init__(self, binary_path: str = "gemini"): def __init__(self, binary_path: str = "gemini"):
""" """
Initializes the adapter with the path to the gemini CLI executable. Initializes the adapter with the path to the gemini CLI executable.
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__] [C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
""" """
@@ -61,9 +63,10 @@ class GeminiCliAdapter:
model: str | None = None, stream_callback: Optional[Callable[[str], None]] = None) -> dict[str, Any]: model: str | None = None, stream_callback: Optional[Callable[[str], None]] = None) -> dict[str, Any]:
""" """
Sends a message to the Gemini CLI and processes the streaming JSON output. Sends a message to the Gemini CLI and processes the streaming JSON output.
Uses non-blocking line-by-line reading to allow stream_callback. Uses non-blocking line-by-line reading to allow stream_callback.
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/multi_agent_conductor.py:run_worker_lifecycle, src/native_orchestrator.py:NativeOrchestrator.execute_ticket, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_get_history_bleed_stats, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast] [C: simulation/user_agent.py:UserSimAgent.generate_response, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
""" """
start_time = time.time() start_time = time.time()
command_parts = [self.binary_path] command_parts = [self.binary_path]
@@ -192,6 +195,7 @@ class GeminiCliAdapter:
def count_tokens(self, contents: list[str]) -> int: def count_tokens(self, contents: list[str]) -> int:
""" """
Provides a character-based token estimation for the Gemini CLI. Provides a character-based token estimation for the Gemini CLI.
Uses 4 chars/token as a conservative average. Uses 4 chars/token as a conservative average.
[C: tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_count_tokens_fallback] [C: tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_count_tokens_fallback]
+49 -4
View File
@@ -265,8 +265,9 @@ class App:
def run(self) -> None: def run(self) -> None:
""" """
Initializes the ImGui runner and starts the main application loop. Initializes the ImGui runner and starts the main application loop.
[C: simulation/sim_base.py:run_sim, src/mcp_client.py:get_git_diff, src/project_manager.py:get_git_commit, src/project_manager.py:get_git_log, 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] [C: simulation/sim_base.py:run_sim, 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]
""" """
if "--headless" in sys.argv: if "--headless" in sys.argv:
print("Headless mode active") print("Headless mode active")
@@ -544,6 +545,7 @@ class App:
def shutdown(self) -> None: def shutdown(self) -> None:
""" """
Cleanly shuts down the app's background tasks and saves state. Cleanly shuts down the app's background tasks and saves state.
[C: tests/conftest.py:app_instance, tests/conftest.py:mock_app] [C: tests/conftest.py:app_instance, tests/conftest.py:mock_app]
""" """
@@ -1026,6 +1028,7 @@ class App:
def _handle_history_logic(self) -> None: def _handle_history_logic(self) -> None:
""" """
Logic for capturing UI state for undo/redo. Logic for capturing UI state for undo/redo.
""" """
if self._is_applying_snapshot: if self._is_applying_snapshot:
@@ -2567,6 +2570,9 @@ class App:
#region: Context Management #region: Context Management
def _render_files_and_media(self) -> None: def _render_files_and_media(self) -> None:
"""
[C: tests/test_gui_fast_render.py:test_render_files_and_media_fast]
"""
avail = imgui.get_content_region_avail().y avail = imgui.get_content_region_avail().y
if not hasattr(self, 'files_screenshots_split'): self.files_screenshots_split = 0.65 if not hasattr(self, 'files_screenshots_split'): self.files_screenshots_split = 0.65
split_y = int(avail * self.files_screenshots_split) split_y = int(avail * self.files_screenshots_split)
@@ -2787,6 +2793,9 @@ class App:
if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_screenshots_panel") if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_screenshots_panel")
def _render_context_composition_panel(self) -> None: def _render_context_composition_panel(self) -> None:
"""
[C: tests/test_auto_slices.py:test_add_all_triggers_auto_slices, tests/test_gui_fast_render.py:test_render_context_composition_panel_fast]
"""
if imgui.collapsing_header("Context Composition##panel"): if imgui.collapsing_header("Context Composition##panel"):
total_lines, total_ast = self._update_context_file_stats() total_lines, total_ast = self._update_context_file_stats()
self._render_context_batch_actions(total_lines, total_ast) self._render_context_batch_actions(total_lines, total_ast)
@@ -2799,6 +2808,9 @@ class App:
self._render_context_presets() self._render_context_presets()
def _render_ast_inspector_modal(self) -> None: def _render_ast_inspector_modal(self) -> None:
"""
[C: tests/test_ast_inspector_extended.py:test_ast_inspector_line_range_parsing]
"""
if self._show_ast_inspector: if self._show_ast_inspector:
imgui.open_popup('AST Inspector') imgui.open_popup('AST Inspector')
self._show_ast_inspector = False self._show_ast_inspector = False
@@ -2933,6 +2945,9 @@ class App:
if not opened: self.ui_inspecting_ast_file = None if not opened: self.ui_inspecting_ast_file = None
def _render_add_context_files_modal(self) -> None: def _render_add_context_files_modal(self) -> None:
"""
[C: tests/test_auto_slices.py:test_add_selected_triggers_auto_slices]
"""
if imgui.begin_popup_modal("Select Context Files", None, imgui.WindowFlags_.always_auto_resize)[0]: if imgui.begin_popup_modal("Select Context Files", None, imgui.WindowFlags_.always_auto_resize)[0]:
imgui.text("Select files from project to add to context:") imgui.text("Select files from project to add to context:")
if imgui.begin_child("ctx_picker_list", imgui.ImVec2(600, 300), True): if imgui.begin_child("ctx_picker_list", imgui.ImVec2(600, 300), True):
@@ -3018,6 +3033,9 @@ class App:
if imgui.button(f"Delete##{name}"): self.delete_context_preset(name) if imgui.button(f"Delete##{name}"): self.delete_context_preset(name)
def _populate_auto_slices(self, f_item: models.FileItem) -> None: def _populate_auto_slices(self, f_item: models.FileItem) -> None:
"""
[C: tests/test_auto_slices.py:test_populate_auto_slices_basic]
"""
from src import mcp_client from src import mcp_client
import re import re
mcp_client.configure([{"path": f_item.path}]) mcp_client.configure([{"path": f_item.path}])
@@ -3415,7 +3433,7 @@ class App:
def _render_discussion_panel(self) -> None: def _render_discussion_panel(self) -> None:
""" """
[C: tests/test_discussion_takes_gui.py:test_render_discussion_tabs, tests/test_discussion_takes_gui.py:test_switching_discussion_via_tabs, tests/test_gui_discussion_tabs.py:test_discussion_tabs_rendered, tests/test_gui_phase4.py:test_track_discussion_toggle, tests/test_gui_symbol_navigation.py:test_render_discussion_panel_symbol_lookup] [C: tests/test_discussion_takes_gui.py:test_render_discussion_tabs, tests/test_discussion_takes_gui.py:test_switching_discussion_via_tabs, tests/test_gui_discussion_tabs.py:test_discussion_tabs_rendered, tests/test_gui_fast_render.py:test_render_discussion_panel_fast, tests/test_gui_phase4.py:test_track_discussion_toggle, tests/test_gui_symbol_navigation.py:test_render_discussion_panel_symbol_lookup]
""" """
if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_discussion_panel") if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_discussion_panel")
self._render_thinking_indicator() self._render_thinking_indicator()
@@ -3654,6 +3672,7 @@ class App:
def _render_synthesis_panel(self) -> None: def _render_synthesis_panel(self) -> None:
""" """
Renders a panel for synthesizing multiple discussion takes. Renders a panel for synthesizing multiple discussion takes.
[C: tests/test_gui_synthesis.py:test_render_synthesis_panel] [C: tests/test_gui_synthesis.py:test_render_synthesis_panel]
""" """
@@ -4678,7 +4697,10 @@ def hello():
imgui.text_colored(imgui.ImVec4(1, 0, 0, 1), f"Error loading beads: {e}") imgui.text_colored(imgui.ImVec4(1, 0, 0, 1), f"Error loading beads: {e}")
def _render_mma_dashboard(self) -> None: def _render_mma_dashboard(self) -> None:
"""Main MMA dashboard interface.""" """
Main MMA dashboard interface.
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress, tests/test_mma_approval_indicators.py:TestMMAApprovalIndicators.test_approval_badge_shown_when_ask_dialog_pending, tests/test_mma_approval_indicators.py:TestMMAApprovalIndicators.test_approval_badge_shown_when_mma_approval_pending, tests/test_mma_approval_indicators.py:TestMMAApprovalIndicators.test_approval_badge_shown_when_spawn_pending, tests/test_mma_approval_indicators.py:TestMMAApprovalIndicators.test_no_approval_badge_when_idle]
"""
if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_mma_dashboard") if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_mma_dashboard")
self._render_mma_focus_selector() self._render_mma_focus_selector()
imgui.separator() imgui.separator()
@@ -4708,6 +4730,9 @@ def hello():
if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_mma_dashboard") if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_mma_dashboard")
def _render_mma_focus_selector(self) -> None: def _render_mma_focus_selector(self) -> None:
"""
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
"""
imgui.text("Focus Agent:"); imgui.same_line() imgui.text("Focus Agent:"); imgui.same_line()
focus_label = self.ui_focus_agent or "All" focus_label = self.ui_focus_agent or "All"
if imgui.begin_combo("##focus_agent", focus_label, imgui.ComboFlags_.width_fit_preview): if imgui.begin_combo("##focus_agent", focus_label, imgui.ComboFlags_.width_fit_preview):
@@ -4795,6 +4820,9 @@ def hello():
imgui.end_popup() imgui.end_popup()
def _render_mma_track_summary(self) -> None: def _render_mma_track_summary(self) -> None:
"""
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
"""
is_nerv = theme.is_nerv_active() is_nerv = theme.is_nerv_active()
track_name = self.active_track.description if self.active_track else "None" track_name = self.active_track.description if self.active_track else "None"
if getattr(self, "ui_project_execution_mode", "native") == "beads": track_name = "Beads Graph" if getattr(self, "ui_project_execution_mode", "native") == "beads": track_name = "Beads Graph"
@@ -4823,15 +4851,24 @@ def hello():
imgui.text_colored(C_LBL, "ETA:"); imgui.same_line(); imgui.text_colored(C_VAL, f"~{int(eta_mins)}m ({remaining} tickets remaining)") imgui.text_colored(C_LBL, "ETA:"); imgui.same_line(); imgui.text_colored(C_VAL, f"~{int(eta_mins)}m ({remaining} tickets remaining)")
def _render_mma_epic_planner(self) -> None: def _render_mma_epic_planner(self) -> None:
"""
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
"""
imgui.text_colored(C_LBL, 'Epic Planning (Tier 1)') imgui.text_colored(C_LBL, 'Epic Planning (Tier 1)')
_, self.ui_epic_input = imgui.input_text_multiline('##epic_input', self.ui_epic_input, imgui.ImVec2(-1, 80)) _, self.ui_epic_input = imgui.input_text_multiline('##epic_input', self.ui_epic_input, imgui.ImVec2(-1, 80))
if imgui.button('Plan Epic (Tier 1)', imgui.ImVec2(-1, 0)): self._cb_plan_epic() if imgui.button('Plan Epic (Tier 1)', imgui.ImVec2(-1, 0)): self._cb_plan_epic()
def _render_mma_conductor_setup(self) -> None: def _render_mma_conductor_setup(self) -> None:
"""
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
"""
if imgui.button("Run Setup Scan"): self._cb_run_conductor_setup() if imgui.button("Run Setup Scan"): self._cb_run_conductor_setup()
if self.ui_conductor_setup_summary: imgui.input_text_multiline("##setup_summary", self.ui_conductor_setup_summary, imgui.ImVec2(-1, 120), imgui.InputTextFlags_.read_only) if self.ui_conductor_setup_summary: imgui.input_text_multiline("##setup_summary", self.ui_conductor_setup_summary, imgui.ImVec2(-1, 120), imgui.InputTextFlags_.read_only)
def _render_mma_track_browser(self) -> None: def _render_mma_track_browser(self) -> None:
"""
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
"""
imgui.text("Track Browser") imgui.text("Track Browser")
if imgui.begin_table("mma_tracks_table", 4, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg | imgui.TableFlags_.resizable): if imgui.begin_table("mma_tracks_table", 4, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg | imgui.TableFlags_.resizable):
imgui.table_setup_column("Title"); imgui.table_setup_column("Status"); imgui.table_setup_column("Progress"); imgui.table_setup_column("Actions"); imgui.table_headers_row() imgui.table_setup_column("Title"); imgui.table_setup_column("Status"); imgui.table_setup_column("Progress"); imgui.table_setup_column("Actions"); imgui.table_headers_row()
@@ -4858,6 +4895,9 @@ def hello():
self.ui_new_track_name = ""; self.ui_new_track_desc = "" self.ui_new_track_name = ""; self.ui_new_track_desc = ""
def _render_mma_global_controls(self) -> None: def _render_mma_global_controls(self) -> None:
"""
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
"""
changed, self.mma_step_mode = imgui.checkbox("Step Mode (HITL)", self.mma_step_mode) changed, self.mma_step_mode = imgui.checkbox("Step Mode (HITL)", self.mma_step_mode)
imgui.same_line(); imgui.text(f"Status: {self.mma_status.upper()}") imgui.same_line(); imgui.text(f"Status: {self.mma_status.upper()}")
if self.controller and hasattr(self.controller, 'engine') and self.controller.engine and hasattr(self.controller.engine, '_pause_event'): if self.controller and hasattr(self.controller, 'engine') and self.controller.engine and hasattr(self.controller.engine, '_pause_event'):
@@ -4876,6 +4916,9 @@ def hello():
if imgui.button("Go to Approval"): pass if imgui.button("Go to Approval"): pass
def _render_mma_usage_section(self) -> None: def _render_mma_usage_section(self) -> None:
"""
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
"""
imgui.text("Tier Usage (Tokens & Cost)") imgui.text("Tier Usage (Tokens & Cost)")
if imgui.begin_table("mma_usage", 5, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg): if imgui.begin_table("mma_usage", 5, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg):
imgui.table_setup_column("Tier"); imgui.table_setup_column("Model"); imgui.table_setup_column("Input"); imgui.table_setup_column("Output"); imgui.table_setup_column("Est. Cost"); imgui.table_headers_row() imgui.table_setup_column("Tier"); imgui.table_setup_column("Model"); imgui.table_setup_column("Input"); imgui.table_setup_column("Output"); imgui.table_setup_column("Est. Cost"); imgui.table_headers_row()
@@ -4939,6 +4982,9 @@ def hello():
if imgui.button(f"Delete##{self.ui_selected_ticket_id}"): self.active_tickets = [t for t in self.active_tickets if str(t.get('id', '')) != self.ui_selected_ticket_id]; self.ui_selected_ticket_id = None; self._push_mma_state_update() if imgui.button(f"Delete##{self.ui_selected_ticket_id}"): self.active_tickets = [t for t in self.active_tickets if str(t.get('id', '')) != self.ui_selected_ticket_id]; self.ui_selected_ticket_id = None; self._push_mma_state_update()
def _render_mma_agent_streams(self) -> None: def _render_mma_agent_streams(self) -> None:
"""
[C: tests/test_gui_progress.py:test_render_mma_dashboard_progress]
"""
imgui.text("Agent Streams") imgui.text("Agent Streams")
if imgui.begin_tab_bar("mma_streams_tabs"): if imgui.begin_tab_bar("mma_streams_tabs"):
for tier, label, sep_flag_attr in [("Tier 1", "Tier 1", "ui_separate_tier1"), ("Tier 2", "Tier 2 (Tech Lead)", "ui_separate_tier2"), ("Tier 3", None, "ui_separate_tier3"), ("Tier 4", "Tier 4 (QA)", "ui_separate_tier4")]: for tier, label, sep_flag_attr in [("Tier 1", "Tier 1", "ui_separate_tier1"), ("Tier 2", "Tier 2 (Tech Lead)", "ui_separate_tier2"), ("Tier 3", None, "ui_separate_tier3"), ("Tier 4", "Tier 4 (QA)", "ui_separate_tier4")]:
@@ -5145,4 +5191,3 @@ def main() -> None:
if __name__ == "__main__": if __name__ == "__main__":
main() main()
+12 -7
View File
@@ -21,7 +21,7 @@ class UISnapshot:
def to_dict(self) -> dict: def to_dict(self) -> dict:
""" """
[C: src/models.py:ExternalEditorConfig.to_dict, src/models.py:MCPConfiguration.to_dict, src/models.py:RAGConfig.to_dict, src/models.py:ToolPreset.to_dict, src/models.py:Track.to_dict, src/models.py:TrackState.to_dict, src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags] [C: src/models.py:ContextPreset.to_dict, src/models.py:ExternalEditorConfig.to_dict, src/models.py:MCPConfiguration.to_dict, src/models.py:RAGConfig.to_dict, src/models.py:ToolPreset.to_dict, src/models.py:Track.to_dict, src/models.py:TrackState.to_dict, src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_context_presets_models.py:test_context_preset_serialization, tests/test_context_presets_models.py:test_file_view_preset_serialization, tests/test_custom_slices_annotations.py:test_file_item_custom_slices_round_trip_annotations, tests/test_custom_slices_annotations.py:test_file_item_custom_slices_serialization_with_annotations, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_history_manager.py:TestHistoryManager.test_snapshot_roundtrip, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_slice_editor_behavior.py:test_add_slice_with_annotations, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
""" """
return { return {
"ai_input": self.ai_input, "ai_input": self.ai_input,
@@ -42,7 +42,7 @@ class UISnapshot:
@classmethod @classmethod
def from_dict(cls, data: dict) -> "UISnapshot": def from_dict(cls, data: dict) -> "UISnapshot":
""" """
[C: src/models.py:ExternalEditorConfig.from_dict, src/models.py:MCPConfiguration.from_dict, src/models.py:RAGConfig.from_dict, src/models.py:ToolPreset.from_dict, src/models.py:Track.from_dict, src/models.py:TrackState.from_dict, src/models.py:load_mcp_config, src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags] [C: src/models.py:ContextPreset.from_dict, src/models.py:ExternalEditorConfig.from_dict, src/models.py:MCPConfiguration.from_dict, src/models.py:RAGConfig.from_dict, src/models.py:ToolPreset.from_dict, src/models.py:Track.from_dict, src/models.py:TrackState.from_dict, src/models.py:load_mcp_config, src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_context_presets_models.py:test_context_preset_from_dict_legacy, tests/test_context_presets_models.py:test_context_preset_serialization, tests/test_context_presets_models.py:test_file_view_preset_serialization, tests/test_custom_slices_annotations.py:test_file_item_custom_slices_deserialization_with_annotations, tests/test_custom_slices_annotations.py:test_file_item_custom_slices_round_trip_annotations, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_history_manager.py:TestHistoryManager.test_snapshot_roundtrip, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_slice_editor_behavior.py:test_add_slice_with_annotations, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
""" """
return cls( return cls(
ai_input=data.get("ai_input", ""), ai_input=data.get("ai_input", ""),
@@ -78,9 +78,10 @@ class HistoryManager:
def push(self, state: typing.Any, description: str) -> None: def push(self, state: typing.Any, description: str) -> None:
""" """
Pushes a new state to the undo stack and clears the redo stack. Pushes a new state to the undo stack and clears the redo stack.
If the undo stack exceeds max_capacity, the oldest state is removed. If the undo stack exceeds max_capacity, the oldest state is removed.
[C: tests/test_history.py:test_jump_to_undo, tests/test_history.py:test_max_capacity, tests/test_history.py:test_push_state, tests/test_history.py:test_redo_cleared_on_push, tests/test_history.py:test_undo_redo] [C: tests/test_history.py:test_jump_to_undo, tests/test_history.py:test_max_capacity, tests/test_history.py:test_push_state, tests/test_history.py:test_redo_cleared_on_push, tests/test_history.py:test_undo_redo, tests/test_history_manager.py:TestHistoryManager.test_get_history_returns_descriptions, tests/test_history_manager.py:TestHistoryManager.test_jump_to_undo, tests/test_history_manager.py:TestHistoryManager.test_push_and_undo, tests/test_history_manager.py:TestHistoryManager.test_push_clears_redo_stack, tests/test_history_manager.py:TestHistoryManager.test_undo_and_redo]
""" """
entry = HistoryEntry(state=state, description=description) entry = HistoryEntry(state=state, description=description)
self._undo_stack.append(entry) self._undo_stack.append(entry)
@@ -91,9 +92,10 @@ class HistoryManager:
def undo(self, current_state: typing.Any, current_description: str = "Current State") -> typing.Optional[HistoryEntry]: def undo(self, current_state: typing.Any, current_description: str = "Current State") -> typing.Optional[HistoryEntry]:
""" """
Undoes the last action by moving the current_state to the redo stack Undoes the last action by moving the current_state to the redo stack
and returning the top of the undo stack. and returning the top of the undo stack.
[C: tests/test_history.py:test_redo_cleared_on_push, tests/test_history.py:test_undo_redo] [C: tests/test_history.py:test_redo_cleared_on_push, tests/test_history.py:test_undo_redo, tests/test_history_manager.py:TestHistoryManager.test_push_and_undo, tests/test_history_manager.py:TestHistoryManager.test_push_clears_redo_stack, tests/test_history_manager.py:TestHistoryManager.test_undo_and_redo, tests/test_history_manager.py:TestHistoryManager.test_undo_no_history_returns_none]
""" """
if not self._undo_stack: if not self._undo_stack:
return None return None
@@ -105,9 +107,10 @@ class HistoryManager:
def redo(self, current_state: typing.Any, current_description: str = "Current State") -> typing.Optional[HistoryEntry]: def redo(self, current_state: typing.Any, current_description: str = "Current State") -> typing.Optional[HistoryEntry]:
""" """
Redoes the last undone action by moving the current_state to the undo stack Redoes the last undone action by moving the current_state to the undo stack
and returning the top of the redo stack. and returning the top of the redo stack.
[C: tests/test_history.py:test_undo_redo] [C: tests/test_history.py:test_undo_redo, tests/test_history_manager.py:TestHistoryManager.test_redo_no_history_returns_none, tests/test_history_manager.py:TestHistoryManager.test_undo_and_redo]
""" """
if not self._redo_stack: if not self._redo_stack:
return None return None
@@ -126,8 +129,9 @@ class HistoryManager:
def get_history(self) -> typing.List[typing.Dict[str, typing.Any]]: def get_history(self) -> typing.List[typing.Dict[str, typing.Any]]:
""" """
Returns a list of descriptions and timestamps for the undo stack. Returns a list of descriptions and timestamps for the undo stack.
[C: tests/test_history.py:test_initial_state, tests/test_history.py:test_push_state] [C: tests/test_history.py:test_initial_state, tests/test_history.py:test_push_state, tests/test_history_manager.py:TestHistoryManager.test_get_history_returns_descriptions]
""" """
return [ return [
{"description": e.description, "timestamp": e.timestamp} {"description": e.description, "timestamp": e.timestamp}
@@ -137,9 +141,10 @@ class HistoryManager:
def jump_to_undo(self, index: int, current_state: typing.Any, current_description: str = "Before Jump") -> typing.Optional[HistoryEntry]: def jump_to_undo(self, index: int, current_state: typing.Any, current_description: str = "Before Jump") -> typing.Optional[HistoryEntry]:
""" """
Jumps to a specific state in the undo stack by moving subsequent states Jumps to a specific state in the undo stack by moving subsequent states
and the current_state to the redo stack. and the current_state to the redo stack.
[C: tests/test_history.py:test_jump_to_undo] [C: tests/test_history.py:test_jump_to_undo, tests/test_history_manager.py:TestHistoryManager.test_jump_to_undo]
""" """
if index < 0 or index >= len(self._undo_stack): if index < 0 or index >= len(self._undo_stack):
return None return None
+45
View File
@@ -5,6 +5,9 @@ from imgui_bundle import imgui_node_editor
def child(id_str: str, size_x: float = 0, size_y: float = 0, flags: int = 0): return _ScopeChild(id_str, size_x, size_y, flags) def child(id_str: str, size_x: float = 0, size_y: float = 0, flags: int = 0): return _ScopeChild(id_str, size_x, size_y, flags)
class _ScopeChild: class _ScopeChild:
def __init__(self, id_str: str, size_x: float | imgui.ImVec2, size_y: float, flags: int): def __init__(self, id_str: str, size_x: float | imgui.ImVec2, size_y: float, flags: int):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._id = id_str self._id = id_str
# Check if size_x is likely an ImVec2 without using isinstance (which breaks with mocks) # Check if size_x is likely an ImVec2 without using isinstance (which breaks with mocks)
if hasattr(size_x, 'x') and hasattr(size_x, 'y'): if hasattr(size_x, 'x') and hasattr(size_x, 'y'):
@@ -30,6 +33,9 @@ class _ScopeGroup:
def id(str_id: str): return _ScopeId(str_id) def id(str_id: str): return _ScopeId(str_id)
class _ScopeId: class _ScopeId:
def __init__(self, str_id: str): def __init__(self, str_id: str):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._id = str_id self._id = str_id
def __enter__(self): def __enter__(self):
imgui.push_id(self._id) imgui.push_id(self._id)
@@ -40,6 +46,9 @@ class _ScopeId:
def menu(label: str): return _ScopeMenu(label) def menu(label: str): return _ScopeMenu(label)
class _ScopeMenu: class _ScopeMenu:
def __init__(self, label: str): def __init__(self, label: str):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._label = label self._label = label
self._active = False self._active = False
def __enter__(self): def __enter__(self):
@@ -53,6 +62,9 @@ class _ScopeMenu:
def menu_bar(): return _ScopeMenuBar() def menu_bar(): return _ScopeMenuBar()
class _ScopeMenuBar: class _ScopeMenuBar:
def __init__(self): def __init__(self):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._active = False self._active = False
def __enter__(self): def __enter__(self):
self._active = imgui.begin_menu_bar() self._active = imgui.begin_menu_bar()
@@ -65,6 +77,9 @@ class _ScopeMenuBar:
def node(name: str): return _ScopeNode(name) def node(name: str): return _ScopeNode(name)
class _ScopeNode: class _ScopeNode:
def __init__(self, name: str): def __init__(self, name: str):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._name = name self._name = name
def __enter__(self): def __enter__(self):
return imgui_node_editor.begin(self._name) return imgui_node_editor.begin(self._name)
@@ -75,6 +90,9 @@ class _ScopeNode:
def popup(id_str: str): return _ScopePopup(id_str) def popup(id_str: str): return _ScopePopup(id_str)
class _ScopePopup: class _ScopePopup:
def __init__(self, id_str: str): def __init__(self, id_str: str):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._id = id_str self._id = id_str
self._active = False self._active = False
def __enter__(self): def __enter__(self):
@@ -88,6 +106,9 @@ class _ScopePopup:
def popup_modal(name: str, visible: bool = True, flags: int = 0): return _ScopePopupModal(name, visible, flags) def popup_modal(name: str, visible: bool = True, flags: int = 0): return _ScopePopupModal(name, visible, flags)
class _ScopePopupModal: class _ScopePopupModal:
def __init__(self, name: str, visible: bool, flags: int): def __init__(self, name: str, visible: bool, flags: int):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._name = name self._name = name
self._visible = visible self._visible = visible
self._flags = flags self._flags = flags
@@ -104,6 +125,9 @@ class _ScopePopupModal:
def style_color(col: int, val: Any): return _ScopeStyleColor(col, val) def style_color(col: int, val: Any): return _ScopeStyleColor(col, val)
class _ScopeStyleColor: class _ScopeStyleColor:
def __init__(self, col: int, val: Any): def __init__(self, col: int, val: Any):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._col = col self._col = col
self._val = val self._val = val
def __enter__(self): def __enter__(self):
@@ -115,6 +139,9 @@ class _ScopeStyleColor:
def style_var(var: int, val: Any): return _ScopeStyleVar(var, val) def style_var(var: int, val: Any): return _ScopeStyleVar(var, val)
class _ScopeStyleVar: class _ScopeStyleVar:
def __init__(self, var: int, val: Any): def __init__(self, var: int, val: Any):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._var = var self._var = var
self._val = val self._val = val
def __enter__(self): def __enter__(self):
@@ -126,6 +153,9 @@ class _ScopeStyleVar:
def table(name: str, columns: int, flags: int = 0): return _ScopeTable(name, columns, flags) def table(name: str, columns: int, flags: int = 0): return _ScopeTable(name, columns, flags)
class _ScopeTable: class _ScopeTable:
def __init__(self, name: str, columns: int, flags: int): def __init__(self, name: str, columns: int, flags: int):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._name = name self._name = name
self._columns = columns self._columns = columns
self._flags = flags self._flags = flags
@@ -141,6 +171,9 @@ class _ScopeTable:
def tab_bar(id_str: str, flags: int = 0): return _ScopeTabBar(id_str, flags) def tab_bar(id_str: str, flags: int = 0): return _ScopeTabBar(id_str, flags)
class _ScopeTabBar: class _ScopeTabBar:
def __init__(self, id_str: str, flags: int): def __init__(self, id_str: str, flags: int):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._id = id_str self._id = id_str
self._flags = flags self._flags = flags
self._active = False self._active = False
@@ -155,6 +188,9 @@ class _ScopeTabBar:
def tab_item(label: str, flags: int = 0): return _ScopeTabItem(label, flags) def tab_item(label: str, flags: int = 0): return _ScopeTabItem(label, flags)
class _ScopeTabItem: class _ScopeTabItem:
def __init__(self, label: str, flags: int): def __init__(self, label: str, flags: int):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._label = label self._label = label
self._flags = flags self._flags = flags
self._expanded = False self._expanded = False
@@ -170,6 +206,9 @@ class _ScopeTabItem:
def text_wrap(wrap_pos: float = 0.0): return _ScopeTextWrap(wrap_pos) def text_wrap(wrap_pos: float = 0.0): return _ScopeTextWrap(wrap_pos)
class _ScopeTextWrap: class _ScopeTextWrap:
def __init__(self, wrap_pos: float): def __init__(self, wrap_pos: float):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._wrap_pos = wrap_pos self._wrap_pos = wrap_pos
def __enter__(self): def __enter__(self):
imgui.push_text_wrap_pos(self._wrap_pos) imgui.push_text_wrap_pos(self._wrap_pos)
@@ -188,6 +227,9 @@ class _ScopeTooltip:
def tree_node_ex(label: str, flags: int = 0): return _ScopeTreeNodeEx(label, flags) def tree_node_ex(label: str, flags: int = 0): return _ScopeTreeNodeEx(label, flags)
class _ScopeTreeNodeEx: class _ScopeTreeNodeEx:
def __init__(self, label: str, flags: int): def __init__(self, label: str, flags: int):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._label = label self._label = label
self._flags = flags self._flags = flags
self._opened = False self._opened = False
@@ -202,6 +244,9 @@ class _ScopeTreeNodeEx:
def window(name: str, visible: bool = True, flags: int = 0): return _ScopeWindow(name, visible, flags) def window(name: str, visible: bool = True, flags: int = 0): return _ScopeWindow(name, visible, flags)
class _ScopeWindow: class _ScopeWindow:
def __init__(self, name: str, visible: bool, flags: int): def __init__(self, name: str, visible: bool, flags: int):
"""
[C: src/mcp_client.py:_DDGParser.__init__, src/mcp_client.py:_TextExtractor.__init__]
"""
self._name = name self._name = name
self._visible = visible self._visible = visible
self._flags = flags self._flags = flags
+3
View File
@@ -8,6 +8,7 @@ from src.log_registry import LogRegistry
class LogPruner: class LogPruner:
""" """
Handles the automated deletion of old and insignificant session logs. Handles the automated deletion of old and insignificant session logs.
Ensures that only whitelisted or significant sessions (based on size/content) Ensures that only whitelisted or significant sessions (based on size/content)
are preserved long-term. are preserved long-term.
@@ -16,6 +17,7 @@ class LogPruner:
def __init__(self, log_registry: LogRegistry, logs_dir: str) -> None: def __init__(self, log_registry: LogRegistry, logs_dir: str) -> None:
""" """
Initializes the LogPruner. Initializes the LogPruner.
Args: Args:
@@ -29,6 +31,7 @@ class LogPruner:
def prune(self, max_age_days: int = 1, min_size_kb: int = 2) -> None: def prune(self, max_age_days: int = 1, min_size_kb: int = 2) -> None:
""" """
Prunes old and small session directories from the logs directory. Prunes old and small session directories from the logs directory.
Deletes session directories that meet the following criteria: Deletes session directories that meet the following criteria:
+9 -1
View File
@@ -48,6 +48,7 @@ from typing import Any
class LogRegistry: class LogRegistry:
""" """
Manages a persistent registry of session logs using a TOML file. Manages a persistent registry of session logs using a TOML file.
Tracks session paths, start times, whitelisting status, and metadata. Tracks session paths, start times, whitelisting status, and metadata.
""" """
@@ -55,6 +56,7 @@ class LogRegistry:
def __init__(self, registry_path: str) -> None: def __init__(self, registry_path: str) -> None:
""" """
Initializes the LogRegistry with a path to the registry file. Initializes the LogRegistry with a path to the registry file.
Args: Args:
@@ -73,6 +75,7 @@ class LogRegistry:
def load_registry(self) -> None: def load_registry(self) -> None:
""" """
Loads the registry data from the TOML file into memory. Loads the registry data from the TOML file into memory.
Handles date/time conversions from TOML-native formats to strings for consistency. Handles date/time conversions from TOML-native formats to strings for consistency.
""" """
@@ -102,6 +105,7 @@ class LogRegistry:
def save_registry(self) -> None: def save_registry(self) -> None:
""" """
Serializes and saves the current registry data to the TOML file. Serializes and saves the current registry data to the TOML file.
Converts internal datetime objects to ISO format strings for compatibility. Converts internal datetime objects to ISO format strings for compatibility.
[C: tests/test_logging_e2e.py:test_logging_e2e] [C: tests/test_logging_e2e.py:test_logging_e2e]
@@ -137,6 +141,7 @@ class LogRegistry:
def register_session(self, session_id: str, path: str, start_time: datetime | str) -> None: def register_session(self, session_id: str, path: str, start_time: datetime | str) -> None:
""" """
Registers a new session in the registry. Registers a new session in the registry.
Args: Args:
@@ -163,6 +168,7 @@ class LogRegistry:
def update_session_metadata(self, session_id: str, message_count: int, errors: int, size_kb: int, whitelisted: bool, reason: str) -> None: def update_session_metadata(self, session_id: str, message_count: int, errors: int, size_kb: int, whitelisted: bool, reason: str) -> None:
""" """
Updates metadata fields for an existing session. Updates metadata fields for an existing session.
Args: Args:
@@ -197,6 +203,7 @@ class LogRegistry:
def is_session_whitelisted(self, session_id: str) -> bool: def is_session_whitelisted(self, session_id: str) -> bool:
""" """
Checks if a specific session is marked as whitelisted. Checks if a specific session is marked as whitelisted.
Args: Args:
@@ -215,6 +222,7 @@ class LogRegistry:
def update_auto_whitelist_status(self, session_id: str) -> None: def update_auto_whitelist_status(self, session_id: str) -> None:
""" """
Analyzes session logs and updates whitelisting status based on heuristics. Analyzes session logs and updates whitelisting status based on heuristics.
Sessions are automatically whitelisted if they contain error keywords, Sessions are automatically whitelisted if they contain error keywords,
have a high message count, or exceed a size threshold. have a high message count, or exceed a size threshold.
@@ -275,6 +283,7 @@ class LogRegistry:
def get_old_non_whitelisted_sessions(self, cutoff_datetime: datetime) -> list[dict[str, Any]]: def get_old_non_whitelisted_sessions(self, cutoff_datetime: datetime) -> list[dict[str, Any]]:
""" """
Retrieves a list of sessions that are older than a specific cutoff time Retrieves a list of sessions that are older than a specific cutoff time
and are not marked as whitelisted. and are not marked as whitelisted.
Also includes non-whitelisted sessions that are empty (message_count=0 or size_kb=0). Also includes non-whitelisted sessions that are empty (message_count=0 or size_kb=0).
@@ -316,4 +325,3 @@ class LogRegistry:
'start_time': start_time_raw 'start_time': start_time_raw
}) })
return old_sessions return old_sessions
+4 -2
View File
@@ -10,6 +10,7 @@ from typing import Optional, Dict, Callable
class MarkdownRenderer: class MarkdownRenderer:
""" """
Hybrid Markdown renderer that uses imgui_md for text/headers Hybrid Markdown renderer that uses imgui_md for text/headers
and ImGuiColorTextEdit for syntax-highlighted code blocks. and ImGuiColorTextEdit for syntax-highlighted code blocks.
""" """
@@ -67,8 +68,9 @@ class MarkdownRenderer:
def render(self, text: str, context_id: str = "default") -> None: def render(self, text: str, context_id: str = "default") -> None:
""" """
Render Markdown text with code block interception. Render Markdown text with code block interception.
[C: tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render] [C: src/theme_2.py:render_post_fx, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
""" """
if not text: if not text:
return return
@@ -167,7 +169,7 @@ def get_renderer() -> MarkdownRenderer:
def render(text: str, context_id: str = "default") -> None: def render(text: str, context_id: str = "default") -> None:
""" """
[C: tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render] [C: src/theme_2.py:render_post_fx, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
""" """
get_renderer().render(text, context_id) get_renderer().render(text, context_id)
+29 -5
View File
@@ -102,12 +102,13 @@ perf_monitor_callback: Optional[Callable[[], dict[str, Any]]] = None
def configure(file_items: list[dict[str, Any]], extra_base_dirs: list[str] | None = None) -> None: def configure(file_items: list[dict[str, Any]], extra_base_dirs: list[str] | None = None) -> None:
""" """
Build the allowlist from aggregate file_items. Build the allowlist from aggregate file_items.
Called by ai_client before each send so the list reflects the current project. Called by ai_client before each send so the list reflects the current project.
file_items : list of dicts from aggregate.build_file_items() file_items : list of dicts from aggregate.build_file_items()
extra_base_dirs : additional directory roots to allow traversal of extra_base_dirs : additional directory roots to allow traversal of
[C: tests/conftest.py:reset_ai_client, tests/test_arch_boundary_phase1.py:TestArchBoundaryPhase1.test_mcp_client_whitelist_enforcement, tests/test_mcp_client_beads.py:test_bd_mcp_tools] [C: tests/conftest.py:reset_ai_client, tests/test_arch_boundary_phase1.py:TestArchBoundaryPhase1.test_mcp_client_whitelist_enforcement, tests/test_mcp_client_beads.py:test_bd_mcp_tools, tests/test_py_struct_tools.py:test_mcp_dispatch_errors, tests/test_py_struct_tools.py:test_mcp_dispatch_integration]
""" """
global _allowed_paths, _base_dirs, _primary_base_dir global _allowed_paths, _base_dirs, _primary_base_dir
_allowed_paths = set() _allowed_paths = set()
@@ -131,6 +132,7 @@ def configure(file_items: list[dict[str, Any]], extra_base_dirs: list[str] | Non
def _is_allowed(path: Path) -> bool: def _is_allowed(path: Path) -> bool:
""" """
Return True if `path` is within the allowlist. Return True if `path` is within the allowlist.
A path is allowed if: A path is allowed if:
- it is explicitly in _allowed_paths, OR - it is explicitly in _allowed_paths, OR
@@ -180,6 +182,7 @@ def _is_allowed(path: Path) -> bool:
def _resolve_and_check(raw_path: str) -> tuple[Path | None, str]: def _resolve_and_check(raw_path: str) -> tuple[Path | None, str]:
""" """
Resolve raw_path and verify it passes the allowlist check. Resolve raw_path and verify it passes the allowlist check.
Returns (resolved_path, error_string). error_string is empty on success. Returns (resolved_path, error_string). error_string is empty on success.
""" """
@@ -243,6 +246,7 @@ def list_directory(path: str) -> str:
def search_files(path: str, pattern: str) -> str: def search_files(path: str, pattern: str) -> str:
""" """
Search for files matching a glob pattern within path. Search for files matching a glob pattern within path.
pattern examples: '*.py', '**/*.toml', 'src/**/*.rs' pattern examples: '*.py', '**/*.toml', 'src/**/*.rs'
""" """
@@ -274,6 +278,7 @@ def search_files(path: str, pattern: str) -> str:
def get_file_summary(path: str) -> str: def get_file_summary(path: str) -> str:
""" """
Return the heuristic summary for a file (same as the initial context block). Return the heuristic summary for a file (same as the initial context block).
For .py files: imports, classes, methods, functions, constants. For .py files: imports, classes, methods, functions, constants.
For .toml: table keys. For .md: headings. Others: line count + preview. For .toml: table keys. For .md: headings. Others: line count + preview.
@@ -294,6 +299,7 @@ def get_file_summary(path: str) -> str:
def py_get_skeleton(path: str) -> str: def py_get_skeleton(path: str) -> str:
""" """
Returns a skeleton of a Python file (preserving docstrings, stripping function bodies). Returns a skeleton of a Python file (preserving docstrings, stripping function bodies).
""" """
p, err = _resolve_and_check(path) p, err = _resolve_and_check(path)
@@ -314,6 +320,7 @@ def py_get_skeleton(path: str) -> str:
def ts_c_get_skeleton(path: str) -> str: def ts_c_get_skeleton(path: str) -> str:
""" """
Returns a skeleton of a C file. Returns a skeleton of a C file.
[C: tests/test_ts_c_tools.py:test_ts_c_get_skeleton] [C: tests/test_ts_c_tools.py:test_ts_c_get_skeleton]
""" """
@@ -331,8 +338,9 @@ def ts_c_get_skeleton(path: str) -> str:
def ts_cpp_get_skeleton(path: str) -> str: def ts_cpp_get_skeleton(path: str) -> str:
""" """
Returns a skeleton of a C++ file. Returns a skeleton of a C++ file.
[C: tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_get_skeleton] [C: tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_get_skeleton]
""" """
p, err = _resolve_and_check(path) p, err = _resolve_and_check(path)
if err: return err if err: return err
@@ -349,6 +357,7 @@ def ts_cpp_get_skeleton(path: str) -> str:
def py_get_code_outline(path: str) -> str: def py_get_code_outline(path: str) -> str:
""" """
Returns a hierarchical outline of a code file (classes, functions, methods with line ranges). Returns a hierarchical outline of a code file (classes, functions, methods with line ranges).
""" """
p, err = _resolve_and_check(path) p, err = _resolve_and_check(path)
@@ -367,6 +376,7 @@ def py_get_code_outline(path: str) -> str:
def ts_c_get_code_outline(path: str) -> str: def ts_c_get_code_outline(path: str) -> str:
""" """
Returns a hierarchical outline of a C file. Returns a hierarchical outline of a C file.
[C: tests/test_ts_c_tools.py:test_ts_c_get_code_outline] [C: tests/test_ts_c_tools.py:test_ts_c_get_code_outline]
""" """
@@ -384,8 +394,9 @@ def ts_c_get_code_outline(path: str) -> str:
def ts_cpp_get_code_outline(path: str) -> str: def ts_cpp_get_code_outline(path: str) -> str:
""" """
Returns a hierarchical outline of a C++ file. Returns a hierarchical outline of a C++ file.
[C: tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_get_code_outline] [C: tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_get_code_outline]
""" """
p, err = _resolve_and_check(path) p, err = _resolve_and_check(path)
if err: return err if err: return err
@@ -415,8 +426,9 @@ def ts_c_get_definition(path: str, name: str) -> str:
def ts_cpp_get_definition(path: str, name: str) -> str: def ts_cpp_get_definition(path: str, name: str) -> str:
""" """
Returns the source code for a specific definition in a C++ file. Returns the source code for a specific definition in a C++ file.
[C: tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition_gencpp] [C: tests/test_ast_masking_core.py:test_ast_masking_gencpp_samples, tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_ts_cpp_tools.py:test_exhaustive_cpp_samples, tests/test_ts_cpp_tools.py:test_exhaustive_gencpp_samples, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition_gencpp]
""" """
p, err = _resolve_and_check(path) p, err = _resolve_and_check(path)
if err: return err if err: return err
@@ -478,6 +490,7 @@ def ts_c_update_definition(path: str, name: str, new_content: str) -> str:
def ts_cpp_update_definition(path: str, name: str, new_content: str) -> str: def ts_cpp_update_definition(path: str, name: str, new_content: str) -> str:
""" """
Surgically replace the definition of a class or function in a C++ file. Surgically replace the definition of a class or function in a C++ file.
[C: tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition_gencpp] [C: tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition, tests/test_ts_cpp_tools.py:test_ts_cpp_update_definition_gencpp]
""" """
@@ -537,6 +550,7 @@ def set_file_slice(path: str, start_line: int, end_line: int, new_content: str)
def edit_file(path: str, old_string: str, new_string: str, replace_all: bool = False) -> str: def edit_file(path: str, old_string: str, new_string: str, replace_all: bool = False) -> str:
""" """
Replace exact string match in a file. Preserves indentation and line endings. Replace exact string match in a file. Preserves indentation and line endings.
Drop-in replacement for native edit tool that destroys 1-space indentation. Drop-in replacement for native edit tool that destroys 1-space indentation.
""" """
@@ -595,6 +609,7 @@ def _get_symbol_node(tree: ast.AST, name: str) -> Optional[ast.AST]:
def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str: def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str:
""" """
Returns (source_code, line_number) for a specific class, function, or method definition. Returns (source_code, line_number) for a specific class, function, or method definition.
If not found, returns an error string. If not found, returns an error string.
""" """
@@ -622,6 +637,7 @@ def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str:
def py_get_definition(path: str, name: str) -> str: def py_get_definition(path: str, name: str) -> str:
""" """
Returns the source code for a specific class, function, or method definition. Returns the source code for a specific class, function, or method definition.
path: Path to the code file. path: Path to the code file.
name: Name of the definition to retrieve (e.g., 'MyClass', 'my_function', 'MyClass.my_method'). name: Name of the definition to retrieve (e.g., 'MyClass', 'my_function', 'MyClass.my_method').
@@ -797,6 +813,7 @@ def py_set_var_declaration(path: str, name: str, new_declaration: str) -> str:
def get_git_diff(path: str, base_rev: str = "HEAD", head_rev: str = "") -> str: def get_git_diff(path: str, base_rev: str = "HEAD", head_rev: str = "") -> str:
""" """
Returns the git diff for a file or directory. Returns the git diff for a file or directory.
base_rev: The base revision (default: HEAD) base_rev: The base revision (default: HEAD)
head_rev: The head revision (optional) head_rev: The head revision (optional)
@@ -1151,6 +1168,7 @@ def fetch_url(url: str) -> str:
def get_ui_performance() -> str: def get_ui_performance() -> str:
""" """
Returns current UI performance metrics (FPS, Frame Time, CPU, Input Lag). Returns current UI performance metrics (FPS, Frame Time, CPU, Input Lag).
[C: tests/test_mcp_perf_tool.py:test_mcp_perf_tool_retrieval] [C: tests/test_mcp_perf_tool.py:test_mcp_perf_tool_retrieval]
""" """
@@ -1262,6 +1280,7 @@ class ExternalMCPManager:
async def add_server(self, config: models.MCPServerConfig): async def add_server(self, config: models.MCPServerConfig):
""" """
Add and start a new MCP server from a configuration object. Add and start a new MCP server from a configuration object.
[C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp.py:test_get_tool_schemas_includes_external] [C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp.py:test_get_tool_schemas_includes_external]
""" """
@@ -1274,6 +1293,7 @@ class ExternalMCPManager:
async def stop_all(self): async def stop_all(self):
""" """
Stop all managed MCP servers and clear the registry. Stop all managed MCP servers and clear the registry.
[C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp.py:test_get_tool_schemas_includes_external, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call] [C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp.py:test_get_tool_schemas_includes_external, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call]
""" """
@@ -1283,6 +1303,7 @@ class ExternalMCPManager:
def get_all_tools(self) -> dict: def get_all_tools(self) -> dict:
""" """
Retrieve a dictionary of all tools available across all managed servers. Retrieve a dictionary of all tools available across all managed servers.
[C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call] [C: tests/test_external_mcp.py:test_external_mcp_real_process, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call]
""" """
@@ -1298,6 +1319,7 @@ class ExternalMCPManager:
async def async_dispatch(self, tool_name: str, tool_input: dict) -> str: async def async_dispatch(self, tool_name: str, tool_input: dict) -> str:
""" """
Dispatch a tool call to the appropriate external MCP server asynchronously. Dispatch a tool call to the appropriate external MCP server asynchronously.
[C: src/rag_engine.py:RAGEngine._async_search_mcp, tests/test_external_mcp.py:test_external_mcp_real_process] [C: src/rag_engine.py:RAGEngine._async_search_mcp, tests/test_external_mcp.py:test_external_mcp_real_process]
""" """
@@ -1310,6 +1332,7 @@ _external_mcp_manager = ExternalMCPManager()
def get_external_mcp_manager() -> ExternalMCPManager: def get_external_mcp_manager() -> ExternalMCPManager:
""" """
Retrieve the global ExternalMCPManager instance. Retrieve the global ExternalMCPManager instance.
[C: tests/test_external_mcp.py:test_get_tool_schemas_includes_external, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call] [C: tests/test_external_mcp.py:test_get_tool_schemas_includes_external, tests/test_external_mcp_e2e.py:test_external_mcp_e2e_refresh_and_call]
""" """
@@ -1319,8 +1342,9 @@ def get_external_mcp_manager() -> ExternalMCPManager:
def dispatch(tool_name: str, tool_input: dict[str, Any]) -> str: def dispatch(tool_name: str, tool_input: dict[str, Any]) -> str:
""" """
Dispatch an MCP tool call by name. Returns the result as a string. Dispatch an MCP tool call by name. Returns the result as a string.
[C: tests/test_gemini_cli_edge_cases.py:test_gemini_cli_parameter_resilience, tests/test_mcp_client_beads.py:test_bd_mcp_tools, tests/test_mcp_ts_integration.py:test_ts_c_get_code_outline_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_signature_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_skeleton_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_update_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_code_outline_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_signature_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_skeleton_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_update_definition_dispatch] [C: tests/test_gemini_cli_edge_cases.py:test_gemini_cli_parameter_resilience, tests/test_mcp_client_beads.py:test_bd_mcp_tools, tests/test_mcp_ts_integration.py:test_ts_c_get_code_outline_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_signature_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_get_skeleton_dispatch, tests/test_mcp_ts_integration.py:test_ts_c_update_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_code_outline_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_definition_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_signature_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_get_skeleton_dispatch, tests/test_mcp_ts_integration.py:test_ts_cpp_update_definition_dispatch, tests/test_py_struct_tools.py:test_mcp_dispatch_errors, tests/test_py_struct_tools.py:test_mcp_dispatch_integration]
""" """
# Handle aliases # Handle aliases
path = str(tool_input.get("path", tool_input.get("file_path", tool_input.get("dir_path", "")))) path = str(tool_input.get("path", tool_input.get("file_path", tool_input.get("dir_path", ""))))
+147
View File
File diff suppressed because one or more lines are too long
+14 -1
View File
@@ -48,6 +48,7 @@ from src.dag_engine import TrackDAG, ExecutionEngine
class WorkerPool: class WorkerPool:
""" """
Manages a pool of worker threads with a concurrency limit. Manages a pool of worker threads with a concurrency limit.
""" """
def __init__(self, max_workers: int = 4): def __init__(self, max_workers: int = 4):
@@ -59,6 +60,7 @@ class WorkerPool:
def spawn(self, ticket_id: str, target: Callable, args: tuple) -> Optional[threading.Thread]: def spawn(self, ticket_id: str, target: Callable, args: tuple) -> Optional[threading.Thread]:
""" """
Spawns a new worker thread if the pool is not full. Spawns a new worker thread if the pool is not full.
Returns the thread object or None if full. Returns the thread object or None if full.
[C: tests/test_parallel_execution.py:test_worker_pool_completion_cleanup, tests/test_parallel_execution.py:test_worker_pool_limit, tests/test_parallel_execution.py:test_worker_pool_tracking] [C: tests/test_parallel_execution.py:test_worker_pool_completion_cleanup, tests/test_parallel_execution.py:test_worker_pool_limit, tests/test_parallel_execution.py:test_worker_pool_tracking]
@@ -108,6 +110,7 @@ class WorkerPool:
class ConductorEngine: class ConductorEngine:
""" """
Orchestrates the execution of tickets within a track. Orchestrates the execution of tickets within a track.
""" """
@@ -148,6 +151,7 @@ class ConductorEngine:
def pause(self) -> None: def pause(self) -> None:
""" """
Pauses the pipeline execution. Pauses the pipeline execution.
[C: tests/test_pipeline_pause.py:test_pause_method, tests/test_pipeline_pause.py:test_resume_method] [C: tests/test_pipeline_pause.py:test_pause_method, tests/test_pipeline_pause.py:test_resume_method]
""" """
@@ -155,6 +159,7 @@ class ConductorEngine:
def resume(self) -> None: def resume(self) -> None:
""" """
Resumes the pipeline execution. Resumes the pipeline execution.
[C: tests/test_pipeline_pause.py:test_resume_method] [C: tests/test_pipeline_pause.py:test_resume_method]
""" """
@@ -162,6 +167,7 @@ class ConductorEngine:
def approve_task(self, task_id: str) -> None: def approve_task(self, task_id: str) -> None:
""" """
Manually transition todo to in_progress and mark engine dirty. Manually transition todo to in_progress and mark engine dirty.
[C: tests/test_execution_engine.py:test_execution_engine_approve_task, tests/test_execution_engine.py:test_execution_engine_step_mode] [C: tests/test_execution_engine.py:test_execution_engine_approve_task, tests/test_execution_engine.py:test_execution_engine_step_mode]
""" """
@@ -170,6 +176,7 @@ class ConductorEngine:
def update_task_status(self, task_id: str, status: str) -> None: def update_task_status(self, task_id: str, status: str) -> None:
""" """
Force-update ticket status and mark engine dirty. Force-update ticket status and mark engine dirty.
[C: tests/test_arch_boundary_phase3.py:TestArchBoundaryPhase3.test_manual_unblock_restores_todo, tests/test_execution_engine.py:test_execution_engine_auto_queue, tests/test_execution_engine.py:test_execution_engine_basic_flow, tests/test_execution_engine.py:test_execution_engine_status_persistence, tests/test_execution_engine.py:test_execution_engine_update_nonexistent_task] [C: tests/test_arch_boundary_phase3.py:TestArchBoundaryPhase3.test_manual_unblock_restores_todo, tests/test_execution_engine.py:test_execution_engine_auto_queue, tests/test_execution_engine.py:test_execution_engine_basic_flow, tests/test_execution_engine.py:test_execution_engine_status_persistence, tests/test_execution_engine.py:test_execution_engine_update_nonexistent_task]
""" """
@@ -178,6 +185,7 @@ class ConductorEngine:
def kill_worker(self, ticket_id: str) -> None: def kill_worker(self, ticket_id: str) -> None:
""" """
Sets the abort event for a worker and attempts to join its thread. Sets the abort event for a worker and attempts to join its thread.
[C: tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread] [C: tests/test_conductor_engine_abort.py:test_kill_worker_sets_abort_and_joins_thread]
""" """
@@ -213,6 +221,7 @@ class ConductorEngine:
def parse_json_tickets(self, json_str: str) -> None: def parse_json_tickets(self, json_str: str) -> None:
""" """
Parses a JSON string of ticket definitions (Godot ECS Flat List format) Parses a JSON string of ticket definitions (Godot ECS Flat List format)
and populates the Track's ticket list. and populates the Track's ticket list.
[C: tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_orchestration_logic.py:test_conductor_engine_parse_json_tickets] [C: tests/test_conductor_engine_v2.py:test_conductor_engine_dynamic_parsing_and_execution, tests/test_orchestration_logic.py:test_conductor_engine_parse_json_tickets]
@@ -244,11 +253,12 @@ class ConductorEngine:
def run(self, md_content: str = "", max_ticks: Optional[int] = None) -> None: def run(self, md_content: str = "", max_ticks: Optional[int] = None) -> None:
""" """
Main execution loop using the DAG engine. Main execution loop using the DAG engine.
Args: Args:
md_content: The full markdown context (history + files) for AI workers. md_content: The full markdown context (history + files) for AI workers.
max_ticks: Optional limit on number of iterations (for testing). max_ticks: Optional limit on number of iterations (for testing).
[C: simulation/sim_base.py:run_sim, src/project_manager.py:get_git_commit, src/project_manager.py:get_git_log, 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] [C: simulation/sim_base.py:run_sim, 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]
""" """
tick_count = 0 tick_count = 0
while True: while True:
@@ -368,6 +378,7 @@ def _queue_put(event_queue: events.AsyncEventQueue, event_name: str, payload) ->
def confirm_execution(payload: str, event_queue: events.AsyncEventQueue, ticket_id: str) -> bool: def confirm_execution(payload: str, event_queue: events.AsyncEventQueue, ticket_id: str) -> bool:
""" """
Pushes an approval request to the GUI and waits for response. Pushes an approval request to the GUI and waits for response.
""" """
dialog_container = [None] dialog_container = [None]
@@ -391,6 +402,7 @@ def confirm_execution(payload: str, event_queue: events.AsyncEventQueue, ticket_
def confirm_spawn(role: str, prompt: str, context_md: str, event_queue: events.AsyncEventQueue, ticket_id: str) -> Tuple[bool, str, str]: def confirm_spawn(role: str, prompt: str, context_md: str, event_queue: events.AsyncEventQueue, ticket_id: str) -> Tuple[bool, str, str]:
""" """
Pushes a spawn approval request to the GUI and waits for response. Pushes a spawn approval request to the GUI and waits for response.
Returns (approved, modified_prompt, modified_context) Returns (approved, modified_prompt, modified_context)
[C: tests/test_spawn_interception_v2.py:run_confirm] [C: tests/test_spawn_interception_v2.py:run_confirm]
@@ -432,6 +444,7 @@ def confirm_spawn(role: str, prompt: str, context_md: str, event_queue: events.A
def run_worker_lifecycle(ticket: Ticket, context: WorkerContext, context_files: List[str] | None = None, event_queue: events.AsyncEventQueue | None = None, engine: Optional['ConductorEngine'] = None, md_content: str = "") -> None: def run_worker_lifecycle(ticket: Ticket, context: WorkerContext, context_files: List[str] | None = None, event_queue: events.AsyncEventQueue | None = None, engine: Optional['ConductorEngine'] = None, md_content: str = "") -> None:
""" """
Simulates the lifecycle of a single agent working on a ticket. Simulates the lifecycle of a single agent working on a ticket.
Calls the AI client and updates the ticket status based on the response. Calls the AI client and updates the ticket status based on the response.
Args: Args:
+2
View File
@@ -12,6 +12,7 @@ from src import paths
def get_track_history_summary() -> str: def get_track_history_summary() -> str:
""" """
Scans conductor/archive/ and conductor/tracks/ to build a summary of past work. Scans conductor/archive/ and conductor/tracks/ to build a summary of past work.
[C: tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_get_track_history_summary, tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_get_track_history_summary_missing_files] [C: tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_get_track_history_summary, tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_get_track_history_summary_missing_files]
""" """
@@ -59,6 +60,7 @@ def get_track_history_summary() -> str:
def generate_tracks(user_request: str, project_config: dict[str, Any], file_items: list[dict[str, Any]], history_summary: Optional[str] = None) -> list[dict[str, Any]]: def generate_tracks(user_request: str, project_config: dict[str, Any], file_items: list[dict[str, Any]], history_summary: Optional[str] = None) -> list[dict[str, Any]]:
""" """
Tier 1 (Strategic PM) call. Tier 1 (Strategic PM) call.
Analyzes the project state and user request to generate a list of Tracks. Analyzes the project state and user request to generate a list of Tracks.
[C: tests/test_orchestration_logic.py:test_generate_tracks, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_malformed_json, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_markdown_wrapped, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_success, tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_generate_tracks_with_history] [C: tests/test_orchestration_logic.py:test_generate_tracks, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_malformed_json, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_markdown_wrapped, tests/test_orchestrator_pm.py:TestOrchestratorPM.test_generate_tracks_success, tests/test_orchestrator_pm_history.py:TestOrchestratorPMHistory.test_generate_tracks_with_history]
+6
View File
@@ -39,6 +39,9 @@ class CodeOutliner:
pass pass
def outline(self, code: str) -> str: def outline(self, code: str) -> str:
"""
[C: tests/test_outline_tool.py:test_code_outliner_imgui_scopes, tests/test_outline_tool.py:test_code_outliner_nested_ifs, tests/test_outline_tool.py:test_code_outliner_type_hints]
"""
code = code.lstrip(chr(0xFEFF)) code = code.lstrip(chr(0xFEFF))
try: try:
tree = ast.parse(code) tree = ast.parse(code)
@@ -55,6 +58,9 @@ class CodeOutliner:
count = [0] count = [0]
def walk(node: ast.AST, indent: int = 0) -> None: def walk(node: ast.AST, indent: int = 0) -> None:
"""
[C: src/summarize.py:_summarise_python]
"""
count[0] += 1 count[0] += 1
if count[0] > 100000: if count[0] > 100000:
raise Exception("Infinite loop detected! " + str(type(node))) raise Exception("Infinite loop detected! " + str(type(node)))
+4
View File
@@ -184,6 +184,9 @@ def get_track_state_dir(track_id: str, project_path: Optional[str] = None) -> Pa
return get_tracks_dir(project_path) / track_id return get_tracks_dir(project_path) / track_id
def get_archive_dir(project_path: Optional[str] = None) -> Path: def get_archive_dir(project_path: Optional[str] = None) -> Path:
"""
[C: tests/test_paths.py:test_conductor_dir_project_relative]
"""
return get_conductor_dir(project_path) / "archive" return get_conductor_dir(project_path) / "archive"
def _resolve_path_info(env_var: str, config_key: str, default: str) -> dict[str, Any]: def _resolve_path_info(env_var: str, config_key: str, default: str) -> dict[str, Any]:
@@ -210,6 +213,7 @@ def get_full_path_info() -> dict[str, dict[str, Any]]:
def reset_resolved() -> None: def reset_resolved() -> None:
""" """
For testing only - clear cached resolutions. For testing only - clear cached resolutions.
[C: tests/conftest.py:reset_paths, tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_gui_phase3.py:test_conductor_setup_scan, tests/test_paths.py:reset_paths, tests/test_project_paths.py:test_get_all_tracks_project_specific, tests/test_project_paths.py:test_get_conductor_dir_default, tests/test_project_paths.py:test_get_conductor_dir_project_specific_with_toml] [C: tests/conftest.py:reset_paths, tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_gui_phase3.py:test_conductor_setup_scan, tests/test_paths.py:reset_paths, tests/test_project_paths.py:test_get_all_tracks_project_specific, tests/test_project_paths.py:test_get_conductor_dir_default, tests/test_project_paths.py:test_get_conductor_dir_project_specific_with_toml]
""" """
+5 -1
View File
@@ -87,6 +87,7 @@ def get_monitor() -> PerformanceMonitor:
class PerformanceMonitor: class PerformanceMonitor:
""" """
Tracks application performance metrics like FPS, frame time, and CPU usage. Tracks application performance metrics like FPS, frame time, and CPU usage.
Supports thread-safe tracking for individual components with efficient moving averages. Supports thread-safe tracking for individual components with efficient moving averages.
""" """
@@ -233,6 +234,7 @@ class PerformanceMonitor:
def get_metrics(self) -> dict[str, float]: def get_metrics(self) -> dict[str, float]:
""" """
Returns current metrics and their moving averages. Thread-safe. Returns current metrics and their moving averages. Thread-safe.
[C: tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_perf_dag.py:test_dag_performance, tests/test_performance_monitor.py:test_perf_monitor_basic_timing, tests/test_performance_monitor.py:test_perf_monitor_component_timing, tests/test_performance_monitor.py:test_perf_monitor_extended_metrics, tests/test_performance_monitor.py:test_perf_monitor_scope_context_manager] [C: tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_perf_dag.py:test_dag_performance, tests/test_performance_monitor.py:test_perf_monitor_basic_timing, tests/test_performance_monitor.py:test_perf_monitor_component_timing, tests/test_performance_monitor.py:test_perf_monitor_extended_metrics, tests/test_performance_monitor.py:test_perf_monitor_scope_context_manager]
""" """
@@ -269,8 +271,9 @@ class PerformanceMonitor:
def get_history(self, key: str) -> List[float]: def get_history(self, key: str) -> List[float]:
""" """
Returns a snapshot of the full history buffer for a specific metric key. Returns a snapshot of the full history buffer for a specific metric key.
[C: tests/test_history.py:test_initial_state, tests/test_history.py:test_push_state] [C: tests/test_history.py:test_initial_state, tests/test_history.py:test_push_state, tests/test_history_manager.py:TestHistoryManager.test_get_history_returns_descriptions]
""" """
with self._lock: with self._lock:
if key in self._history: if key in self._history:
@@ -281,6 +284,7 @@ class PerformanceMonitor:
def scope(self, name: str) -> PerformanceScope: def scope(self, name: str) -> PerformanceScope:
""" """
Returns a context manager for timing a component. Returns a context manager for timing a component.
[C: tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_performance_monitor.py:test_perf_monitor_scope_context_manager] [C: tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_performance_monitor.py:test_perf_monitor_scope_context_manager]
""" """
+1
View File
@@ -26,6 +26,7 @@ class PersonaManager:
def load_all(self) -> Dict[str, Persona]: def load_all(self) -> Dict[str, Persona]:
""" """
Merges global and project personas into a single dictionary. Merges global and project personas into a single dictionary.
[C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project] [C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
""" """
+2
View File
@@ -19,6 +19,7 @@ class PresetManager:
def load_all(self) -> Dict[str, Preset]: def load_all(self) -> Dict[str, Preset]:
""" """
Merges global and project presets into a single dictionary. Merges global and project presets into a single dictionary.
[C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project] [C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
""" """
@@ -45,6 +46,7 @@ class PresetManager:
def save_preset(self, preset: Preset, scope: str = "project") -> None: def save_preset(self, preset: Preset, scope: str = "project") -> None:
""" """
Saves a preset to either the global or project-specific TOML file. Saves a preset to either the global or project-specific TOML file.
[C: tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_preset_manager.py:test_save_preset_project_no_root, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project] [C: tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_preset_manager.py:test_save_preset_project_no_root, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
""" """
+18
View File
@@ -30,6 +30,7 @@ def parse_ts(s: str) -> Optional[datetime.datetime]:
def entry_to_str(entry: dict[str, Any]) -> str: def entry_to_str(entry: dict[str, Any]) -> str:
""" """
Serialise a disc entry dict -> stored string. Serialise a disc entry dict -> stored string.
[C: tests/test_thinking_persistence.py:test_entry_to_str_with_thinking] [C: tests/test_thinking_persistence.py:test_entry_to_str_with_thinking]
""" """
@@ -50,6 +51,7 @@ def entry_to_str(entry: dict[str, Any]) -> str:
def str_to_entry(raw: str, roles: list[str]) -> dict[str, Any]: def str_to_entry(raw: str, roles: list[str]) -> dict[str, Any]:
""" """
Parse a stored string back to a disc entry dict. Parse a stored string back to a disc entry dict.
[C: tests/test_thinking_persistence.py:test_str_to_entry_with_thinking] [C: tests/test_thinking_persistence.py:test_str_to_entry_with_thinking]
""" """
@@ -152,6 +154,7 @@ def default_project(name: str = "unnamed") -> dict[str, Any]:
def get_history_path(project_path: Union[str, Path]) -> Path: def get_history_path(project_path: Union[str, Path]) -> Path:
""" """
Return the Path to the sibling history TOML file for a given project. Return the Path to the sibling history TOML file for a given project.
[C: tests/test_history_management.py:test_save_separation] [C: tests/test_history_management.py:test_save_separation]
""" """
@@ -161,6 +164,7 @@ def get_history_path(project_path: Union[str, Path]) -> Path:
def load_project(path: Union[str, Path]) -> dict[str, Any]: def load_project(path: Union[str, Path]) -> dict[str, Any]:
""" """
Load a project TOML file. Load a project TOML file.
Automatically migrates legacy 'discussion' keys to a sibling history file. Automatically migrates legacy 'discussion' keys to a sibling history file.
[C: tests/test_history_management.py:test_history_persistence_across_turns, tests/test_history_management.py:test_migration_on_load, tests/test_project_manager_modes.py:test_load_save_execution_mode, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_project_serialization.py:TestProjectSerialization.test_fileitem_roundtrip] [C: tests/test_history_management.py:test_history_persistence_across_turns, tests/test_history_management.py:test_migration_on_load, tests/test_project_manager_modes.py:test_load_save_execution_mode, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_project_serialization.py:TestProjectSerialization.test_fileitem_roundtrip]
@@ -185,6 +189,7 @@ def load_project(path: Union[str, Path]) -> dict[str, Any]:
def load_history(project_path: Union[str, Path]) -> dict[str, Any]: def load_history(project_path: Union[str, Path]) -> dict[str, Any]:
""" """
Load the segregated discussion history from its dedicated TOML file. Load the segregated discussion history from its dedicated TOML file.
[C: tests/test_thinking_persistence.py:test_save_and_load_history_with_thinking_segments] [C: tests/test_thinking_persistence.py:test_save_and_load_history_with_thinking_segments]
""" """
@@ -196,6 +201,7 @@ def load_history(project_path: Union[str, Path]) -> dict[str, Any]:
def clean_nones(data: Any) -> Any: def clean_nones(data: Any) -> Any:
""" """
Recursively remove None values from a dictionary/list. Recursively remove None values from a dictionary/list.
[C: tests/test_thinking_persistence.py:test_clean_nones_removes_thinking] [C: tests/test_thinking_persistence.py:test_clean_nones_removes_thinking]
""" """
@@ -208,6 +214,7 @@ def clean_nones(data: Any) -> Any:
def save_project(proj: dict[str, Any], path: Union[str, Path], disc_data: Optional[dict[str, Any]] = None) -> None: def save_project(proj: dict[str, Any], path: Union[str, Path], disc_data: Optional[dict[str, Any]] = None) -> None:
""" """
Save the project TOML. Save the project TOML.
If 'discussion' is present in proj, it is moved to the sibling history file. If 'discussion' is present in proj, it is moved to the sibling history file.
[C: tests/test_history_management.py:test_history_persistence_across_turns, tests/test_history_management.py:test_save_separation, tests/test_project_manager_modes.py:test_load_save_execution_mode, tests/test_project_serialization.py:TestProjectSerialization.test_fileitem_roundtrip, tests/test_thinking_persistence.py:test_save_and_load_history_with_thinking_segments] [C: tests/test_history_management.py:test_history_persistence_across_turns, tests/test_history_management.py:test_save_separation, tests/test_project_manager_modes.py:test_load_save_execution_mode, tests/test_project_serialization.py:TestProjectSerialization.test_fileitem_roundtrip, tests/test_thinking_persistence.py:test_save_and_load_history_with_thinking_segments]
@@ -270,6 +277,7 @@ def flat_config(proj: dict[str, Any], disc_name: Optional[str] = None, track_id:
def save_context_preset(project_dict: dict, preset_name: str, files: list[str], screenshots: list[str]) -> None: def save_context_preset(project_dict: dict, preset_name: str, files: list[str], screenshots: list[str]) -> None:
""" """
Save a named context preset (files + screenshots) into the project dict. Save a named context preset (files + screenshots) into the project dict.
[C: tests/test_context_presets.py:test_save_context_preset] [C: tests/test_context_presets.py:test_save_context_preset]
""" """
@@ -282,6 +290,7 @@ def save_context_preset(project_dict: dict, preset_name: str, files: list[str],
def load_context_preset(project_dict: dict, preset_name: str) -> dict: def load_context_preset(project_dict: dict, preset_name: str) -> dict:
""" """
Return the files and screenshots for a named preset. Return the files and screenshots for a named preset.
[C: tests/test_context_presets.py:test_load_context_preset, tests/test_context_presets.py:test_load_nonexistent_preset] [C: tests/test_context_presets.py:test_load_context_preset, tests/test_context_presets.py:test_load_nonexistent_preset]
""" """
@@ -291,6 +300,7 @@ def load_context_preset(project_dict: dict, preset_name: str) -> dict:
def delete_context_preset(project_dict: dict, preset_name: str) -> None: def delete_context_preset(project_dict: dict, preset_name: str) -> None:
""" """
Remove a named preset if it exists. Remove a named preset if it exists.
[C: tests/test_context_presets.py:test_delete_context_preset, tests/test_context_presets.py:test_delete_nonexistent_preset_no_error] [C: tests/test_context_presets.py:test_delete_context_preset, tests/test_context_presets.py:test_delete_nonexistent_preset_no_error]
""" """
@@ -301,6 +311,7 @@ def delete_context_preset(project_dict: dict, preset_name: str) -> None:
def save_track_state(track_id: str, state: 'TrackState', base_dir: Union[str, Path] = ".") -> None: def save_track_state(track_id: str, state: 'TrackState', base_dir: Union[str, Path] = ".") -> None:
""" """
Saves a TrackState object to conductor/tracks/<track_id>/state.toml. Saves a TrackState object to conductor/tracks/<track_id>/state.toml.
[C: tests/test_project_manager_tracks.py:test_get_all_tracks_with_state, tests/test_track_state_persistence.py:test_track_state_persistence] [C: tests/test_project_manager_tracks.py:test_get_all_tracks_with_state, tests/test_track_state_persistence.py:test_track_state_persistence]
""" """
@@ -314,6 +325,7 @@ def save_track_state(track_id: str, state: 'TrackState', base_dir: Union[str, Pa
def load_track_state(track_id: str, base_dir: Union[str, Path] = ".") -> Optional['TrackState']: def load_track_state(track_id: str, base_dir: Union[str, Path] = ".") -> Optional['TrackState']:
""" """
Loads a TrackState object from conductor/tracks/<track_id>/state.toml. Loads a TrackState object from conductor/tracks/<track_id>/state.toml.
[C: tests/test_track_state_persistence.py:test_track_state_persistence] [C: tests/test_track_state_persistence.py:test_track_state_persistence]
""" """
@@ -328,6 +340,7 @@ def load_track_state(track_id: str, base_dir: Union[str, Path] = ".") -> Optiona
def load_track_history(track_id: str, base_dir: Union[str, Path] = ".") -> list[str]: def load_track_history(track_id: str, base_dir: Union[str, Path] = ".") -> list[str]:
""" """
Loads the discussion history for a specific track from its state.toml. Loads the discussion history for a specific track from its state.toml.
Returns a list of entry strings formatted with @timestamp. Returns a list of entry strings formatted with @timestamp.
""" """
@@ -346,6 +359,7 @@ def load_track_history(track_id: str, base_dir: Union[str, Path] = ".") -> list[
def save_track_history(track_id: str, history: list[str], base_dir: Union[str, Path] = ".") -> None: def save_track_history(track_id: str, history: list[str], base_dir: Union[str, Path] = ".") -> None:
""" """
Saves the discussion history for a specific track to its state.toml. Saves the discussion history for a specific track to its state.toml.
'history' is expected to be a list of formatted strings. 'history' is expected to be a list of formatted strings.
""" """
@@ -360,6 +374,7 @@ def save_track_history(track_id: str, history: list[str], base_dir: Union[str, P
def get_all_tracks(base_dir: Union[str, Path] = ".") -> list[dict[str, Any]]: def get_all_tracks(base_dir: Union[str, Path] = ".") -> list[dict[str, Any]]:
""" """
Scans the conductor/tracks/ directory and returns a list of dictionaries Scans the conductor/tracks/ directory and returns a list of dictionaries
containing track metadata: 'id', 'title', 'status', 'complete', 'total', containing track metadata: 'id', 'title', 'status', 'complete', 'total',
and 'progress' (0.0 to 1.0). and 'progress' (0.0 to 1.0).
@@ -428,6 +443,7 @@ def get_all_tracks(base_dir: Union[str, Path] = ".") -> list[dict[str, Any]]:
def calculate_track_progress(tickets: list) -> dict: def calculate_track_progress(tickets: list) -> dict:
""" """
Calculates track progress based on ticket statuses. Calculates track progress based on ticket statuses.
percentage (float), completed (int), total (int), in_progress (int), blocked (int), todo (int) percentage (float), completed (int), total (int), in_progress (int), blocked (int), todo (int)
[C: tests/test_progress_viz.py:test_calculate_track_progress_all_completed, tests/test_progress_viz.py:test_calculate_track_progress_all_todo, tests/test_progress_viz.py:test_calculate_track_progress_empty, tests/test_progress_viz.py:test_calculate_track_progress_mixed] [C: tests/test_progress_viz.py:test_calculate_track_progress_all_completed, tests/test_progress_viz.py:test_calculate_track_progress_all_todo, tests/test_progress_viz.py:test_calculate_track_progress_empty, tests/test_progress_viz.py:test_calculate_track_progress_mixed]
@@ -463,6 +479,7 @@ def calculate_track_progress(tickets: list) -> dict:
def branch_discussion(project_dict: dict, source_id: str, new_id: str, message_index: int) -> None: def branch_discussion(project_dict: dict, source_id: str, new_id: str, message_index: int) -> None:
""" """
Creates a new discussion in project_dict['discussion']['discussions'] by copying Creates a new discussion in project_dict['discussion']['discussions'] by copying
the history from source_id up to (and including) message_index, and sets active to new_id. the history from source_id up to (and including) message_index, and sets active to new_id.
[C: tests/test_discussion_takes.py:TestDiscussionTakes.test_branch_discussion_creates_new_take] [C: tests/test_discussion_takes.py:TestDiscussionTakes.test_branch_discussion_creates_new_take]
@@ -483,6 +500,7 @@ def branch_discussion(project_dict: dict, source_id: str, new_id: str, message_i
def promote_take(project_dict: dict, take_id: str, new_id: str) -> None: def promote_take(project_dict: dict, take_id: str, new_id: str) -> None:
""" """
Renames a take_id to new_id in the discussions dict. Renames a take_id to new_id in the discussions dict.
[C: tests/test_discussion_takes.py:TestDiscussionTakes.test_promote_take_renames_discussion] [C: tests/test_discussion_takes.py:TestDiscussionTakes.test_promote_take_renames_discussion]
""" """
+5
View File
@@ -44,6 +44,7 @@ def _now_ts() -> str:
def open_session(label: Optional[str] = None) -> None: def open_session(label: Optional[str] = None) -> None:
""" """
Called once at GUI startup. Creates the log directories if needed and Called once at GUI startup. Creates the log directories if needed and
opens the log files for this session within a sub-directory. opens the log files for this session within a sub-directory.
[C: tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_logging_e2e.py:test_logging_e2e, tests/test_session_logger_optimization.py:test_log_tool_call_saves_in_session_scripts, tests/test_session_logger_optimization.py:test_log_tool_output_saves_in_session_outputs, tests/test_session_logger_optimization.py:test_session_directory_and_subdirectories_creation, tests/test_session_logger_reset.py:test_reset_session, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry] [C: tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_logging_e2e.py:test_logging_e2e, tests/test_session_logger_optimization.py:test_log_tool_call_saves_in_session_scripts, tests/test_session_logger_optimization.py:test_log_tool_output_saves_in_session_outputs, tests/test_session_logger_optimization.py:test_session_directory_and_subdirectories_creation, tests/test_session_logger_reset.py:test_reset_session, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry]
@@ -89,6 +90,7 @@ def open_session(label: Optional[str] = None) -> None:
def close_session() -> None: def close_session() -> None:
""" """
Flush and close all log files. Called on clean exit. Flush and close all log files. Called on clean exit.
[C: tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_logging_e2e.py:e2e_setup, tests/test_logging_e2e.py:test_logging_e2e, tests/test_session_logger_optimization.py:temp_session_setup, tests/test_session_logger_reset.py:temp_logs, tests/test_session_logging.py:temp_logs] [C: tests/test_app_controller_offloading.py:tmp_session_dir, tests/test_logging_e2e.py:e2e_setup, tests/test_logging_e2e.py:test_logging_e2e, tests/test_session_logger_optimization.py:temp_session_setup, tests/test_session_logger_reset.py:temp_logs, tests/test_session_logging.py:temp_logs]
""" """
@@ -136,6 +138,7 @@ def log_api_hook(method: str, path: str, payload: str) -> None:
def log_comms(entry: dict[str, Any]) -> None: def log_comms(entry: dict[str, Any]) -> None:
""" """
Append one comms entry to the comms log file as a JSON-L line. Append one comms entry to the comms log file as a JSON-L line.
Thread-safe (GIL + line-buffered file). Thread-safe (GIL + line-buffered file).
[C: tests/test_logging_e2e.py:test_logging_e2e] [C: tests/test_logging_e2e.py:test_logging_e2e]
@@ -150,6 +153,7 @@ def log_comms(entry: dict[str, Any]) -> None:
def log_tool_call(script: str, result: str, script_path: Optional[str]) -> Optional[str]: def log_tool_call(script: str, result: str, script_path: Optional[str]) -> Optional[str]:
""" """
Append a tool-call record to the toolcalls log and write the PS1 script to Append a tool-call record to the toolcalls log and write the PS1 script to
the session's scripts directory. Returns the path of the written script file. the session's scripts directory. Returns the path of the written script file.
[C: tests/test_session_logger_optimization.py:test_log_tool_call_saves_in_session_scripts] [C: tests/test_session_logger_optimization.py:test_log_tool_call_saves_in_session_scripts]
@@ -194,6 +198,7 @@ def log_tool_call(script: str, result: str, script_path: Optional[str]) -> Optio
def log_tool_output(content: str) -> Optional[str]: def log_tool_output(content: str) -> Optional[str]:
""" """
Save tool output content to a unique file in the session's outputs directory. Save tool output content to a unique file in the session's outputs directory.
Returns the path of the written file. Returns the path of the written file.
[C: tests/test_session_logger_optimization.py:test_log_tool_output_returns_none_if_no_session, tests/test_session_logger_optimization.py:test_log_tool_output_saves_in_session_outputs] [C: tests/test_session_logger_optimization.py:test_log_tool_output_returns_none_if_no_session, tests/test_session_logger_optimization.py:test_log_tool_output_saves_in_session_outputs]
+1
View File
@@ -3,6 +3,7 @@ from imgui_bundle import imgui
def draw_soft_shadow(draw_list: imgui.ImDrawList, p_min: imgui.ImVec2, p_max: imgui.ImVec2, color: imgui.ImVec4, shadow_size: float = 10.0, rounding: float = 0.0) -> None: def draw_soft_shadow(draw_list: imgui.ImDrawList, p_min: imgui.ImVec2, p_max: imgui.ImVec2, color: imgui.ImVec4, shadow_size: float = 10.0, rounding: float = 0.0) -> None:
""" """
Simulates a soft shadow effect by drawing multiple concentric rounded rectangles Simulates a soft shadow effect by drawing multiple concentric rounded rectangles
with decreasing alpha values. This is a faux-shader effect using primitive batching. with decreasing alpha values. This is a faux-shader effect using primitive batching.
""" """
+1
View File
@@ -54,6 +54,7 @@ def _build_subprocess_env() -> dict[str, str]:
def run_powershell(script: str, base_dir: str, qa_callback: Optional[Callable[[str], str]] = None, patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str: def run_powershell(script: str, base_dir: str, qa_callback: Optional[Callable[[str], str]] = None, patch_callback: Optional[Callable[[str, str], Optional[str]]] = None) -> str:
""" """
Run a PowerShell script with working directory set to base_dir. Run a PowerShell script with working directory set to base_dir.
Returns a string combining stdout, stderr, and exit code. Returns a string combining stdout, stderr, and exit code.
Environment is configured via mcp_env.toml (project root). Environment is configured via mcp_env.toml (project root).
+3
View File
@@ -154,6 +154,7 @@ _SUMMARISERS: dict[str, Callable[[Path, str], str]] = {
def summarise_file(path: Path, content: str) -> str: def summarise_file(path: Path, content: str) -> str:
""" """
Return a compact markdown summary string for a single file. Return a compact markdown summary string for a single file.
`content` is the already-read file text (or an error string). `content` is the already-read file text (or an error string).
[C: tests/test_subagent_summarization.py:test_summarise_file_integration] [C: tests/test_subagent_summarization.py:test_summarise_file_integration]
@@ -193,6 +194,7 @@ def summarise_file(path: Path, content: str) -> str:
def summarise_items(file_items: list[dict[str, Any]]) -> list[dict[str, Any]]: def summarise_items(file_items: list[dict[str, Any]]) -> list[dict[str, Any]]:
""" """
Given a list of file_item dicts (as returned by aggregate.build_file_items), Given a list of file_item dicts (as returned by aggregate.build_file_items),
return a parallel list of dicts with an added `summary` key. return a parallel list of dicts with an added `summary` key.
""" """
@@ -212,6 +214,7 @@ def summarise_items(file_items: list[dict[str, Any]]) -> list[dict[str, Any]]:
def build_summary_markdown(file_items: list[dict[str, Any]]) -> str: def build_summary_markdown(file_items: list[dict[str, Any]]) -> str:
""" """
Build a compact markdown string of file summaries, suitable for the Build a compact markdown string of file summaries, suitable for the
initial <context> block instead of full file contents. initial <context> block instead of full file contents.
""" """
+7 -1
View File
@@ -5,6 +5,7 @@ from typing import Optional, Dict
def get_file_hash(content: str) -> str: def get_file_hash(content: str) -> str:
""" """
Returns SHA256 hash of the content. Returns SHA256 hash of the content.
[C: tests/test_summary_cache.py:test_get_file_hash, tests/test_summary_cache.py:test_summary_cache] [C: tests/test_summary_cache.py:test_get_file_hash, tests/test_summary_cache.py:test_summary_cache]
""" """
@@ -13,6 +14,7 @@ def get_file_hash(content: str) -> str:
class SummaryCache: class SummaryCache:
""" """
A hash-based cache for file summaries to avoid redundant processing. A hash-based cache for file summaries to avoid redundant processing.
Invalidates when content hash changes. Invalidates when content hash changes.
""" """
@@ -28,8 +30,9 @@ class SummaryCache:
def load(self) -> None: def load(self) -> None:
""" """
Loads cache from disk. Loads cache from disk.
[C: src/tool_presets.py:ToolPresetManager._read_raw, src/workspace_manager.py:WorkspaceManager._load_file, tests/test_gui_phase3.py:test_create_track, tests/test_history_management.py:test_save_separation, tests/test_saved_presets_sim.py:test_preset_manager_modal, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry, tests/test_visual_sim_gui_ux.py:test_gui_track_creation] [C: src/tool_presets.py:ToolPresetManager._read_raw, src/workspace_manager.py:WorkspaceManager._load_file, tests/test_gui_phase3.py:test_create_track, tests/test_history_management.py:test_save_separation, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry]
""" """
if self.cache_file.exists(): if self.cache_file.exists():
try: try:
@@ -49,6 +52,7 @@ class SummaryCache:
def get_summary(self, file_path: str, content_hash: str) -> Optional[str]: def get_summary(self, file_path: str, content_hash: str) -> Optional[str]:
""" """
Returns cached summary if hash matches, otherwise None. Returns cached summary if hash matches, otherwise None.
[C: tests/test_summary_cache.py:test_summary_cache, tests/test_summary_cache.py:test_summary_cache_lru] [C: tests/test_summary_cache.py:test_summary_cache, tests/test_summary_cache.py:test_summary_cache_lru]
""" """
@@ -62,6 +66,7 @@ class SummaryCache:
def set_summary(self, file_path: str, content_hash: str, summary: str) -> None: def set_summary(self, file_path: str, content_hash: str, summary: str) -> None:
""" """
Stores summary in cache and saves to disk. Stores summary in cache and saves to disk.
[C: tests/test_summary_cache.py:test_summary_cache, tests/test_summary_cache.py:test_summary_cache_lru] [C: tests/test_summary_cache.py:test_summary_cache, tests/test_summary_cache.py:test_summary_cache_lru]
""" """
@@ -80,6 +85,7 @@ class SummaryCache:
def clear(self) -> None: def clear(self) -> None:
""" """
Clears the cache both in-memory and on disk. Clears the cache both in-memory and on disk.
[C: tests/conftest.py:reset_ai_client] [C: tests/conftest.py:reset_ai_client]
""" """
+3
View File
@@ -23,6 +23,7 @@ from src.theme_nerv_fx import CRTFilter, AlertPulsing, StatusFlicker
def _c(r: int, g: int, b: int, a: int = 255) -> tuple[float, float, float, float]: def _c(r: int, g: int, b: int, a: int = 255) -> tuple[float, float, float, float]:
""" """
Convert 0-255 RGBA to 0.0-1.0 floats. Convert 0-255 RGBA to 0.0-1.0 floats.
[C: src/theme_nerv.py:module] [C: src/theme_nerv.py:module]
""" """
@@ -283,7 +284,9 @@ def set_child_transparency(val: float) -> None:
def apply(palette_name: str) -> None: def apply(palette_name: str) -> None:
""" """
Apply a named palette by setting all ImGui style colors and applying global professional styling. Apply a named palette by setting all ImGui style colors and applying global professional styling.
[C: tests/test_theme.py:test_theme_apply_sets_rounding_and_padding]
""" """
global _current_palette global _current_palette
_current_palette = palette_name _current_palette = palette_name
+1
View File
@@ -63,6 +63,7 @@ NERV_PALETTE = {
def apply_nerv() -> None: def apply_nerv() -> None:
""" """
Apply NERV theme with hard edges and specific palette. Apply NERV theme with hard edges and specific palette.
[C: tests/test_theme_nerv.py:test_apply_nerv_sets_rounding_and_colors] [C: tests/test_theme_nerv.py:test_apply_nerv_sets_rounding_and_colors]
""" """
+1
View File
@@ -5,6 +5,7 @@ from src.models import ThinkingSegment
def parse_thinking_trace(text: str) -> Tuple[List[ThinkingSegment], str]: def parse_thinking_trace(text: str) -> Tuple[List[ThinkingSegment], str]:
""" """
Parses thinking segments from text and returns (segments, response_content). Parses thinking segments from text and returns (segments, response_content).
Support extraction of thinking traces from <thinking>...</thinking>, <thought>...</thought>, Support extraction of thinking traces from <thinking>...</thinking>, <thought>...</thought>,
and blocks prefixed with Thinking:. and blocks prefixed with Thinking:.
+1
View File
@@ -59,6 +59,7 @@ class ToolPresetManager:
def load_all(self) -> Dict[str, ToolPreset]: def load_all(self) -> Dict[str, ToolPreset]:
""" """
Backward compatibility for load_all(). Backward compatibility for load_all().
[C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project] [C: tests/test_persona_manager.py:test_delete_persona, tests/test_persona_manager.py:test_load_all_merged, tests/test_persona_manager.py:test_save_persona, tests/test_preset_manager.py:test_delete_preset, tests/test_preset_manager.py:test_load_all_merged, tests/test_preset_manager.py:test_save_preset_global, tests/test_preset_manager.py:test_save_preset_project, tests/test_presets.py:TestPresetManager.test_delete_preset, tests/test_presets.py:TestPresetManager.test_project_overwrites_global, tests/test_presets.py:TestPresetManager.test_save_and_load_global, tests/test_presets.py:TestPresetManager.test_save_and_load_project]
""" """
+1
View File
@@ -26,6 +26,7 @@ class WorkspaceManager:
def load_all_profiles(self) -> Dict[str, WorkspaceProfile]: def load_all_profiles(self) -> Dict[str, WorkspaceProfile]:
""" """
Merges global and project profiles into a single dictionary. Merges global and project profiles into a single dictionary.
[C: tests/test_workspace_manager.py:test_delete_profile, tests/test_workspace_manager.py:test_load_all_profiles_merged, tests/test_workspace_manager.py:test_save_profile_global_and_project] [C: tests/test_workspace_manager.py:test_delete_profile, tests/test_workspace_manager.py:test_load_all_profiles_merged, tests/test_workspace_manager.py:test_save_profile_global_and_project]
""" """
+5
View File
@@ -71,6 +71,7 @@ class VerificationLogger:
def reset_paths() -> Generator[None, None, None]: def reset_paths() -> Generator[None, None, None]:
""" """
Autouse fixture that resets the paths global state before each test. Autouse fixture that resets the paths global state before each test.
""" """
from src import paths from src import paths
@@ -82,6 +83,7 @@ def reset_paths() -> Generator[None, None, None]:
def reset_ai_client() -> Generator[None, None, None]: def reset_ai_client() -> Generator[None, None, None]:
""" """
Autouse fixture that resets the ai_client global state before each test. Autouse fixture that resets the ai_client global state before each test.
This is critical for preventing state pollution between tests. This is critical for preventing state pollution between tests.
""" """
@@ -131,6 +133,7 @@ def kill_process_tree(pid: int | None) -> None:
def mock_app() -> Generator[App, None, None]: def mock_app() -> Generator[App, None, None]:
""" """
Mock version of the App for simple unit tests that don't need a loop. Mock version of the App for simple unit tests that don't need a loop.
""" """
with ( with (
@@ -163,6 +166,7 @@ def mock_app() -> Generator[App, None, None]:
def app_instance() -> Generator[App, None, None]: def app_instance() -> Generator[App, None, None]:
""" """
Centralized App instance with all external side effects mocked. Centralized App instance with all external side effects mocked.
Matches the pattern used in test_token_viz.py and test_gui_phase4.py. Matches the pattern used in test_token_viz.py and test_gui_phase4.py.
[C: tests/test_gui2_events.py:test_app_subscribes_to_events] [C: tests/test_gui2_events.py:test_app_subscribes_to_events]
@@ -199,6 +203,7 @@ def app_instance() -> Generator[App, None, None]:
def live_gui() -> Generator[tuple[subprocess.Popen, str], None, None]: def live_gui() -> Generator[tuple[subprocess.Popen, str], None, None]:
""" """
Session-scoped fixture that starts sloppy.py with --enable-test-hooks. Session-scoped fixture that starts sloppy.py with --enable-test-hooks.
Includes high-signal environment telemetry and workspace isolation. Includes high-signal environment telemetry and workspace isolation.
""" """
+1
View File
@@ -10,6 +10,7 @@ from src.api_hook_client import ApiHookClient
def wait_for_value(client, field, expected, timeout=5): def wait_for_value(client, field, expected, timeout=5):
""" """
Polls the GUI state until a field matches the expected value. Polls the GUI state until a field matches the expected value.
[C: tests/test_live_workflow.py:test_full_live_workflow] [C: tests/test_live_workflow.py:test_full_live_workflow]
""" """
+1
View File
@@ -3,6 +3,7 @@ from src import ai_client
def test_list_models_gemini_cli() -> None: def test_list_models_gemini_cli() -> None:
""" """
Verifies that 'ai_client.list_models' correctly returns a list of models Verifies that 'ai_client.list_models' correctly returns a list of models
for the 'gemini_cli' provider. for the 'gemini_cli' provider.
""" """
+2
View File
@@ -37,6 +37,7 @@ def app_controller(tmp_session_dir):
def test_on_comms_entry_tool_result_offloading(app_controller, tmp_session_dir): def test_on_comms_entry_tool_result_offloading(app_controller, tmp_session_dir):
""" """
Test that _on_comms_entry offloads tool_result output to a separate file. Test that _on_comms_entry offloads tool_result output to a separate file.
""" """
output_content = "This is a large tool output that should be offloaded." output_content = "This is a large tool output that should be offloaded."
@@ -83,6 +84,7 @@ def test_on_comms_entry_tool_result_offloading(app_controller, tmp_session_dir):
def test_on_tool_log_offloading(app_controller, tmp_session_dir): def test_on_tool_log_offloading(app_controller, tmp_session_dir):
""" """
Test that _on_tool_log calls session_logger.log_tool_call and log_tool_output. Test that _on_tool_log calls session_logger.log_tool_call and log_tool_output.
""" """
script = "Get-Process" script = "Get-Process"
+2
View File
@@ -9,6 +9,7 @@ from src import mcp_client
async def test_execute_tool_calls_concurrently_timing(): async def test_execute_tool_calls_concurrently_timing():
""" """
Verifies that _execute_tool_calls_concurrently runs tools in parallel. Verifies that _execute_tool_calls_concurrently runs tools in parallel.
Total time should be approx 0.5s for 3 tools each taking 0.5s. Total time should be approx 0.5s for 3 tools each taking 0.5s.
""" """
@@ -67,6 +68,7 @@ async def test_execute_tool_calls_concurrently_timing():
async def test_execute_tool_calls_concurrently_exception_handling(): async def test_execute_tool_calls_concurrently_exception_handling():
""" """
Verifies that if one tool call fails, it doesn't crash the whole group if caught, Verifies that if one tool call fails, it doesn't crash the whole group if caught,
but currently gather is used WITHOUT return_exceptions=True, so it should re-raise. but currently gather is used WITHOUT return_exceptions=True, so it should re-raise.
""" """
+1
View File
@@ -22,6 +22,7 @@ class TestCliToolBridgeMapping(unittest.TestCase):
def test_mapping_from_api_format(self, mock_request: MagicMock, mock_stdout: MagicMock, mock_stdin: MagicMock) -> None: def test_mapping_from_api_format(self, mock_request: MagicMock, mock_stdout: MagicMock, mock_stdin: MagicMock) -> None:
""" """
Verify that bridge correctly maps 'id', 'name', 'input' (Gemini API format) Verify that bridge correctly maps 'id', 'name', 'input' (Gemini API format)
into tool_name and tool_input for the hook client. into tool_name and tool_input for the hook client.
""" """
+1
View File
@@ -7,6 +7,7 @@ import threading
def test_conductor_abort_event_populated(): def test_conductor_abort_event_populated():
""" """
Test that ConductorEngine populates _abort_events when spawning a worker. Test that ConductorEngine populates _abort_events when spawning a worker.
""" """
# 1. Mock WorkerPool.spawn to return a mock thread # 1. Mock WorkerPool.spawn to return a mock thread
@@ -4,6 +4,7 @@ from src.api_hook_client import ApiHookClient
def simulate_conductor_phase_completion(client: ApiHookClient, track_id: str, phase_name: str) -> bool: def simulate_conductor_phase_completion(client: ApiHookClient, track_id: str, phase_name: str) -> bool:
""" """
Simulates the Conductor agent's logic for phase completion using ApiHookClient. Simulates the Conductor agent's logic for phase completion using ApiHookClient.
""" """
try: try:
@@ -24,6 +25,7 @@ def simulate_conductor_phase_completion(client: ApiHookClient, track_id: str, ph
def test_conductor_integrates_api_hook_client_for_verification(live_gui) -> None: def test_conductor_integrates_api_hook_client_for_verification(live_gui) -> None:
""" """
Verify that Conductor's simulated phase completion logic properly integrates Verify that Conductor's simulated phase completion logic properly integrates
with the ApiHookClient and the live Hook Server. with the ApiHookClient and the live Hook Server.
""" """
+2
View File
@@ -8,6 +8,7 @@ from src.models import Track
def test_conductor_engine_initializes_empty_worker_and_abort_dicts() -> None: def test_conductor_engine_initializes_empty_worker_and_abort_dicts() -> None:
""" """
Test that ConductorEngine correctly initializes _active_workers and _abort_events as empty dictionaries. Test that ConductorEngine correctly initializes _active_workers and _abort_events as empty dictionaries.
""" """
# Mock the track object # Mock the track object
@@ -24,6 +25,7 @@ def test_conductor_engine_initializes_empty_worker_and_abort_dicts() -> None:
def test_kill_worker_sets_abort_and_joins_thread() -> None: def test_kill_worker_sets_abort_and_joins_thread() -> None:
""" """
Test kill_worker: mock a running thread in _active_workers, call kill_worker, Test kill_worker: mock a running thread in _active_workers, call kill_worker,
assert abort_event is set and thread is joined. assert abort_event is set and thread is joined.
""" """
+10
View File
@@ -10,6 +10,7 @@ from src import ai_client
def test_conductor_engine_initialization() -> None: def test_conductor_engine_initialization() -> None:
""" """
Test that ConductorEngine can be initialized with a Track. Test that ConductorEngine can be initialized with a Track.
""" """
track = Track(id="test_track", description="Test Track") track = Track(id="test_track", description="Test Track")
@@ -20,6 +21,7 @@ def test_conductor_engine_initialization() -> None:
def test_conductor_engine_run_executes_tickets_in_order(monkeypatch: pytest.MonkeyPatch, vlogger) -> None: def test_conductor_engine_run_executes_tickets_in_order(monkeypatch: pytest.MonkeyPatch, vlogger) -> None:
""" """
Test that run iterates through executable tickets and calls the worker lifecycle. Test that run iterates through executable tickets and calls the worker lifecycle.
""" """
ticket1 = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1") ticket1 = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1")
@@ -67,6 +69,7 @@ def test_conductor_engine_run_executes_tickets_in_order(monkeypatch: pytest.Monk
def test_run_worker_lifecycle_calls_ai_client_send(monkeypatch: pytest.MonkeyPatch) -> None: def test_run_worker_lifecycle_calls_ai_client_send(monkeypatch: pytest.MonkeyPatch) -> None:
""" """
Test that run_worker_lifecycle triggers the AI client and updates ticket status on success. Test that run_worker_lifecycle triggers the AI client and updates ticket status on success.
""" """
ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1") ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1")
@@ -88,6 +91,7 @@ def test_run_worker_lifecycle_calls_ai_client_send(monkeypatch: pytest.MonkeyPat
def test_run_worker_lifecycle_context_injection(monkeypatch: pytest.MonkeyPatch) -> None: def test_run_worker_lifecycle_context_injection(monkeypatch: pytest.MonkeyPatch) -> None:
""" """
Test that run_worker_lifecycle can take a context_files list and injects AST views into the prompt. Test that run_worker_lifecycle can take a context_files list and injects AST views into the prompt.
""" """
ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1") ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1")
@@ -134,6 +138,7 @@ def test_run_worker_lifecycle_context_injection(monkeypatch: pytest.MonkeyPatch)
def test_run_worker_lifecycle_handles_blocked_response(monkeypatch: pytest.MonkeyPatch) -> None: def test_run_worker_lifecycle_handles_blocked_response(monkeypatch: pytest.MonkeyPatch) -> None:
""" """
Test that run_worker_lifecycle marks the ticket as blocked if the AI indicates it cannot proceed. Test that run_worker_lifecycle marks the ticket as blocked if the AI indicates it cannot proceed.
""" """
ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1") ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="worker1")
@@ -151,6 +156,7 @@ def test_run_worker_lifecycle_handles_blocked_response(monkeypatch: pytest.Monke
def test_run_worker_lifecycle_step_mode_confirmation(monkeypatch: pytest.MonkeyPatch) -> None: def test_run_worker_lifecycle_step_mode_confirmation(monkeypatch: pytest.MonkeyPatch) -> None:
""" """
Test that run_worker_lifecycle passes confirm_execution to ai_client.send when step_mode is True. Test that run_worker_lifecycle passes confirm_execution to ai_client.send when step_mode is True.
Verify that if confirm_execution is called (simulated by mocking ai_client.send to call its callback), Verify that if confirm_execution is called (simulated by mocking ai_client.send to call its callback),
the flow works as expected. the flow works as expected.
@@ -188,6 +194,7 @@ def test_run_worker_lifecycle_step_mode_confirmation(monkeypatch: pytest.MonkeyP
def test_run_worker_lifecycle_step_mode_rejection(monkeypatch: pytest.MonkeyPatch) -> None: def test_run_worker_lifecycle_step_mode_rejection(monkeypatch: pytest.MonkeyPatch) -> None:
""" """
Verify that if confirm_execution returns False, the logic (in ai_client, which we simulate here) Verify that if confirm_execution returns False, the logic (in ai_client, which we simulate here)
would prevent execution. In run_worker_lifecycle, we just check if it's passed. would prevent execution. In run_worker_lifecycle, we just check if it's passed.
""" """
@@ -213,6 +220,7 @@ def test_run_worker_lifecycle_step_mode_rejection(monkeypatch: pytest.MonkeyPatc
def test_conductor_engine_dynamic_parsing_and_execution(monkeypatch: pytest.MonkeyPatch, vlogger) -> None: def test_conductor_engine_dynamic_parsing_and_execution(monkeypatch: pytest.MonkeyPatch, vlogger) -> None:
""" """
Test that parse_json_tickets correctly populates the track and run executes them in dependency order. Test that parse_json_tickets correctly populates the track and run executes them in dependency order.
""" """
import json import json
@@ -281,6 +289,7 @@ def test_conductor_engine_dynamic_parsing_and_execution(monkeypatch: pytest.Monk
def test_run_worker_lifecycle_pushes_response_via_queue(monkeypatch: pytest.MonkeyPatch) -> None: def test_run_worker_lifecycle_pushes_response_via_queue(monkeypatch: pytest.MonkeyPatch) -> None:
""" """
Test that run_worker_lifecycle pushes a 'response' event with the correct stream_id Test that run_worker_lifecycle pushes a 'response' event with the correct stream_id
via _queue_put when event_queue is provided. via _queue_put when event_queue is provided.
""" """
@@ -307,6 +316,7 @@ def test_run_worker_lifecycle_pushes_response_via_queue(monkeypatch: pytest.Monk
def test_run_worker_lifecycle_token_usage_from_comms_log(monkeypatch: pytest.MonkeyPatch) -> None: def test_run_worker_lifecycle_token_usage_from_comms_log(monkeypatch: pytest.MonkeyPatch) -> None:
""" """
Test that run_worker_lifecycle reads token usage from the comms log and Test that run_worker_lifecycle reads token usage from the comms log and
updates engine.tier_usage['Tier 3'] with real input/output token counts. updates engine.tier_usage['Tier 3'] with real input/output token counts.
""" """
+9
View File
@@ -10,6 +10,7 @@ from src.dag_engine import TrackDAG
def test_get_ready_tasks_linear(): def test_get_ready_tasks_linear():
""" """
Verifies ready tasks detection in a simple linear dependency chain. Verifies ready tasks detection in a simple linear dependency chain.
""" """
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1") t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1")
@@ -22,6 +23,7 @@ def test_get_ready_tasks_linear():
def test_get_ready_tasks_branching(): def test_get_ready_tasks_branching():
""" """
Verifies ready tasks detection in a branching dependency graph where multiple tasks Verifies ready tasks detection in a branching dependency graph where multiple tasks
are unlocked simultaneously after a prerequisite is met. are unlocked simultaneously after a prerequisite is met.
""" """
@@ -38,6 +40,7 @@ def test_get_ready_tasks_branching():
def test_has_cycle_no_cycle(): def test_has_cycle_no_cycle():
""" """
Validates that an acyclic graph is correctly identified as not having cycles. Validates that an acyclic graph is correctly identified as not having cycles.
""" """
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1") t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1")
@@ -48,6 +51,7 @@ def test_has_cycle_no_cycle():
def test_has_cycle_direct_cycle(): def test_has_cycle_direct_cycle():
""" """
Validates that a direct cycle (A depends on B, B depends on A) is correctly detected. Validates that a direct cycle (A depends on B, B depends on A) is correctly detected.
""" """
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T2"]) t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T2"])
@@ -58,6 +62,7 @@ def test_has_cycle_direct_cycle():
def test_has_cycle_indirect_cycle(): def test_has_cycle_indirect_cycle():
""" """
Validates that an indirect cycle (A->B->C->A) is correctly detected. Validates that an indirect cycle (A->B->C->A) is correctly detected.
""" """
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T3"]) t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T3"])
@@ -69,6 +74,7 @@ def test_has_cycle_indirect_cycle():
def test_has_cycle_complex_no_cycle(): def test_has_cycle_complex_no_cycle():
""" """
Validates cycle detection in a complex graph that merges branches but remains acyclic. Validates cycle detection in a complex graph that merges branches but remains acyclic.
""" """
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1") t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1")
@@ -81,6 +87,7 @@ def test_has_cycle_complex_no_cycle():
def test_get_ready_tasks_multiple_deps(): def test_get_ready_tasks_multiple_deps():
""" """
Validates that a task is not marked ready until ALL of its dependencies are completed. Validates that a task is not marked ready until ALL of its dependencies are completed.
""" """
t1 = Ticket(id="T1", description="desc", status="completed", assigned_to="worker1") t1 = Ticket(id="T1", description="desc", status="completed", assigned_to="worker1")
@@ -95,6 +102,7 @@ def test_get_ready_tasks_multiple_deps():
def test_topological_sort(): def test_topological_sort():
""" """
Verifies that tasks are correctly ordered by dependencies regardless of input order. Verifies that tasks are correctly ordered by dependencies regardless of input order.
""" """
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1") t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1")
@@ -107,6 +115,7 @@ def test_topological_sort():
def test_topological_sort_cycle(): def test_topological_sort_cycle():
""" """
Verifies that topological sorting safely aborts and raises ValueError when a cycle is present. Verifies that topological sorting safely aborts and raises ValueError when a cycle is present.
""" """
t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T2"]) t1 = Ticket(id="T1", description="desc", status="todo", assigned_to="worker1", depends_on=["T2"])
+5
View File
@@ -13,6 +13,7 @@ from src import project_manager
def test_credentials_error_mentions_deepseek(monkeypatch: pytest.MonkeyPatch) -> None: def test_credentials_error_mentions_deepseek(monkeypatch: pytest.MonkeyPatch) -> None:
""" """
Verify that the error message shown when credentials.toml is missing Verify that the error message shown when credentials.toml is missing
includes deepseek instructions. includes deepseek instructions.
""" """
@@ -27,6 +28,7 @@ def test_credentials_error_mentions_deepseek(monkeypatch: pytest.MonkeyPatch) ->
def test_default_project_includes_reasoning_role() -> None: def test_default_project_includes_reasoning_role() -> None:
""" """
Verify that 'Reasoning' is included in the default discussion roles Verify that 'Reasoning' is included in the default discussion roles
to support DeepSeek-R1 reasoning traces. to support DeepSeek-R1 reasoning traces.
""" """
@@ -37,6 +39,7 @@ def test_default_project_includes_reasoning_role() -> None:
def test_gui_providers_list() -> None: def test_gui_providers_list() -> None:
""" """
Check if 'deepseek' is in the GUI's provider list. Check if 'deepseek' is in the GUI's provider list.
""" """
from src.models import PROVIDERS from src.models import PROVIDERS
@@ -45,6 +48,7 @@ def test_gui_providers_list() -> None:
def test_deepseek_model_listing() -> None: def test_deepseek_model_listing() -> None:
""" """
Verify that list_models for deepseek returns expected models. Verify that list_models for deepseek returns expected models.
""" """
models = ai_client.list_models("deepseek") models = ai_client.list_models("deepseek")
@@ -54,6 +58,7 @@ def test_deepseek_model_listing() -> None:
def test_gui_provider_list_via_hooks(live_gui: Any) -> None: def test_gui_provider_list_via_hooks(live_gui: Any) -> None:
""" """
Verify 'deepseek' is present in the GUI provider list using API hooks. Verify 'deepseek' is present in the GUI provider list using API hooks.
""" """
from api_hook_client import ApiHookClient from api_hook_client import ApiHookClient
+7
View File
@@ -5,6 +5,7 @@ from src import ai_client
def test_deepseek_model_selection() -> None: def test_deepseek_model_selection() -> None:
""" """
Verifies that ai_client.set_provider('deepseek', 'deepseek-chat') correctly updates the internal state. Verifies that ai_client.set_provider('deepseek', 'deepseek-chat') correctly updates the internal state.
""" """
ai_client.set_provider("deepseek", "deepseek-chat") ai_client.set_provider("deepseek", "deepseek-chat")
@@ -15,6 +16,7 @@ def test_deepseek_model_selection() -> None:
def test_deepseek_completion_logic(mock_post: MagicMock) -> None: def test_deepseek_completion_logic(mock_post: MagicMock) -> None:
""" """
Verifies that ai_client.send() correctly calls the DeepSeek API and returns content. Verifies that ai_client.send() correctly calls the DeepSeek API and returns content.
""" """
ai_client.set_provider("deepseek", "deepseek-chat") ai_client.set_provider("deepseek", "deepseek-chat")
@@ -34,6 +36,7 @@ def test_deepseek_completion_logic(mock_post: MagicMock) -> None:
def test_deepseek_reasoning_logic(mock_post: MagicMock) -> None: def test_deepseek_reasoning_logic(mock_post: MagicMock) -> None:
""" """
Verifies that reasoning_content is captured and wrapped in <thinking> tags. Verifies that reasoning_content is captured and wrapped in <thinking> tags.
""" """
ai_client.set_provider("deepseek", "deepseek-reasoner") ai_client.set_provider("deepseek", "deepseek-reasoner")
@@ -56,6 +59,7 @@ def test_deepseek_reasoning_logic(mock_post: MagicMock) -> None:
def test_deepseek_tool_calling(mock_post: MagicMock) -> None: def test_deepseek_tool_calling(mock_post: MagicMock) -> None:
""" """
Verifies that DeepSeek provider correctly identifies and executes tool calls. Verifies that DeepSeek provider correctly identifies and executes tool calls.
""" """
ai_client.set_provider("deepseek", "deepseek-chat") ai_client.set_provider("deepseek", "deepseek-chat")
@@ -98,6 +102,7 @@ def test_deepseek_tool_calling(mock_post: MagicMock) -> None:
def test_deepseek_streaming(mock_post: MagicMock) -> None: def test_deepseek_streaming(mock_post: MagicMock) -> None:
""" """
Verifies that DeepSeek provider correctly aggregates streaming chunks. Verifies that DeepSeek provider correctly aggregates streaming chunks.
""" """
ai_client.set_provider("deepseek", "deepseek-chat") ai_client.set_provider("deepseek", "deepseek-chat")
@@ -121,6 +126,7 @@ def test_deepseek_streaming(mock_post: MagicMock) -> None:
def test_deepseek_payload_verification(mock_post: MagicMock) -> None: def test_deepseek_payload_verification(mock_post: MagicMock) -> None:
""" """
Verifies that the correct JSON payload (tools, history, params) is sent to DeepSeek. Verifies that the correct JSON payload (tools, history, params) is sent to DeepSeek.
""" """
ai_client.set_provider("deepseek", "deepseek-chat") ai_client.set_provider("deepseek", "deepseek-chat")
@@ -149,6 +155,7 @@ def test_deepseek_payload_verification(mock_post: MagicMock) -> None:
def test_deepseek_reasoner_payload_verification(mock_post: MagicMock) -> None: def test_deepseek_reasoner_payload_verification(mock_post: MagicMock) -> None:
""" """
Verifies that deepseek-reasoner payload excludes tools and temperature. Verifies that deepseek-reasoner payload excludes tools and temperature.
""" """
ai_client.set_provider("deepseek", "deepseek-reasoner") ai_client.set_provider("deepseek", "deepseek-reasoner")
+1
View File
@@ -12,6 +12,7 @@ from src.ai_client import get_gemini_cache_stats, reset_session
def test_get_gemini_cache_stats_with_mock_client() -> None: def test_get_gemini_cache_stats_with_mock_client() -> None:
""" """
Test that get_gemini_cache_stats correctly processes cache lists Test that get_gemini_cache_stats correctly processes cache lists
from a mocked client instance. from a mocked client instance.
""" """
+1
View File
@@ -12,6 +12,7 @@ def app_instance(monkeypatch: pytest.MonkeyPatch) -> type[App]:
def test_app_subscribes_to_events(app_instance: type[App]) -> None: def test_app_subscribes_to_events(app_instance: type[App]) -> None:
""" """
This test checks that the App's __init__ method subscribes the necessary This test checks that the App's __init__ method subscribes the necessary
event handlers to the ai_client.events emitter. event handlers to the ai_client.events emitter.
""" """
+2
View File
@@ -3,6 +3,7 @@ from src.gui_2 import App
def test_gui2_hubs_exist_in_show_windows(app_instance: App) -> None: def test_gui2_hubs_exist_in_show_windows(app_instance: App) -> None:
""" """
Verifies that the new consolidated Hub windows are defined in the App's show_windows. Verifies that the new consolidated Hub windows are defined in the App's show_windows.
This ensures they will be available in the 'Windows' menu. This ensures they will be available in the 'Windows' menu.
""" """
@@ -20,6 +21,7 @@ def test_gui2_hubs_exist_in_show_windows(app_instance: App) -> None:
def test_gui2_old_windows_removed_from_show_windows(app_instance: App) -> None: def test_gui2_old_windows_removed_from_show_windows(app_instance: App) -> None:
""" """
Verifies that the old fragmented windows are removed from show_windows. Verifies that the old fragmented windows are removed from show_windows.
Note: Message, Response, and Tool Calls are kept as they are now optional standalone windows. Note: Message, Response, and Tool Calls are kept as they are now optional standalone windows.
""" """
+1
View File
@@ -6,6 +6,7 @@ from src import ai_client
def test_mcp_tool_call_is_dispatched(app_instance: App) -> None: def test_mcp_tool_call_is_dispatched(app_instance: App) -> None:
""" """
This test verifies that when the AI returns a tool call for an MCP function, This test verifies that when the AI returns a tool call for an MCP function,
the ai_client correctly dispatches it to mcp_client. the ai_client correctly dispatches it to mcp_client.
This will fail until mcp_client is properly integrated. This will fail until mcp_client is properly integrated.
+3
View File
@@ -26,6 +26,7 @@ def cleanup_callback_file() -> None:
def test_gui2_set_value_hook_works(live_gui: Any) -> None: def test_gui2_set_value_hook_works(live_gui: Any) -> None:
""" """
Tests that the 'set_value' GUI hook is correctly implemented. Tests that the 'set_value' GUI hook is correctly implemented.
""" """
client = ApiHookClient() client = ApiHookClient()
@@ -42,6 +43,7 @@ def test_gui2_set_value_hook_works(live_gui: Any) -> None:
def test_gui2_click_hook_works(live_gui: Any) -> None: def test_gui2_click_hook_works(live_gui: Any) -> None:
""" """
Tests that the 'click' GUI hook for the 'Reset' button is implemented. Tests that the 'click' GUI hook for the 'Reset' button is implemented.
""" """
client = ApiHookClient() client = ApiHookClient()
@@ -60,6 +62,7 @@ def test_gui2_click_hook_works(live_gui: Any) -> None:
def test_gui2_custom_callback_hook_works(live_gui: Any) -> None: def test_gui2_custom_callback_hook_works(live_gui: Any) -> None:
""" """
Tests that the 'custom_callback' GUI hook is correctly implemented. Tests that the 'custom_callback' GUI hook is correctly implemented.
""" """
client = ApiHookClient() client = ApiHookClient()
+2
View File
@@ -20,6 +20,7 @@ _shared_metrics = {}
def test_performance_benchmarking(live_gui: tuple) -> None: def test_performance_benchmarking(live_gui: tuple) -> None:
""" """
Collects performance metrics for the current GUI script over a 5-second window. Collects performance metrics for the current GUI script over a 5-second window.
Ensures the application does not lock up and can report its internal state. Ensures the application does not lock up and can report its internal state.
""" """
@@ -67,6 +68,7 @@ def test_performance_benchmarking(live_gui: tuple) -> None:
def test_performance_baseline_check() -> None: def test_performance_baseline_check() -> None:
""" """
Verifies that we have successfully collected performance metrics for sloppy.py Verifies that we have successfully collected performance metrics for sloppy.py
and that they meet the minimum 30 FPS baseline. and that they meet the minimum 30 FPS baseline.
""" """
+1
View File
@@ -15,6 +15,7 @@ def test_diagnostics_panel_initialization(app_instance: Any) -> None:
def test_diagnostics_history_updates(app_instance: Any) -> None: def test_diagnostics_history_updates(app_instance: Any) -> None:
""" """
Verifies that the internal performance history is updated correctly. Verifies that the internal performance history is updated correctly.
This logic is inside the render loop in gui_2.py, but we can test This logic is inside the render loop in gui_2.py, but we can test
the data structure and initialization. the data structure and initialization.
@@ -11,6 +11,7 @@ from api_hook_client import ApiHookClient
def test_idle_performance_requirements(live_gui) -> None: def test_idle_performance_requirements(live_gui) -> None:
""" """
Requirement: GUI must maintain stable performance on idle. Requirement: GUI must maintain stable performance on idle.
""" """
# Warmup to ensure GUI is ready # Warmup to ensure GUI is ready
+3
View File
@@ -12,6 +12,7 @@ from src import paths
def test_track_proposal_editing(app_instance): def test_track_proposal_editing(app_instance):
""" """
Verifies the structural integrity of track proposal items. Verifies the structural integrity of track proposal items.
Ensures that track proposals can be edited and removed from the active list. Ensures that track proposals can be edited and removed from the active list.
""" """
@@ -35,6 +36,7 @@ def test_track_proposal_editing(app_instance):
def test_conductor_setup_scan(app_instance, tmp_path, monkeypatch): def test_conductor_setup_scan(app_instance, tmp_path, monkeypatch):
""" """
Verifies that the conductor setup scan properly iterates through the conductor directory, Verifies that the conductor setup scan properly iterates through the conductor directory,
counts files and lines, and identifies active tracks. counts files and lines, and identifies active tracks.
""" """
@@ -63,6 +65,7 @@ def test_conductor_setup_scan(app_instance, tmp_path, monkeypatch):
def test_create_track(app_instance, tmp_path): def test_create_track(app_instance, tmp_path):
""" """
Verifies that _cb_create_track properly creates the track folder Verifies that _cb_create_track properly creates the track folder
and populates the necessary boilerplate files (spec.md, plan.md, metadata.json). and populates the necessary boilerplate files (spec.md, plan.md, metadata.json).
""" """
+1
View File
@@ -3,6 +3,7 @@ import time
def test_gui_startup_smoke(live_gui): def test_gui_startup_smoke(live_gui):
""" """
Smoke test to ensure the GUI starts and remains running. Smoke test to ensure the GUI starts and remains running.
""" """
proc, _ = live_gui proc, _ = live_gui
+1
View File
@@ -5,6 +5,7 @@ from src.api_hook_client import ApiHookClient
def test_text_viewer_state_update(live_gui) -> None: def test_text_viewer_state_update(live_gui) -> None:
""" """
Verifies that we can set text viewer state and it is reflected in GUI state. Verifies that we can set text viewer state and it is reflected in GUI state.
""" """
client = ApiHookClient() client = ApiHookClient()
+3
View File
@@ -17,6 +17,7 @@ from src.gui_2 import App
def test_telemetry_data_updates_correctly(app_instance: Any) -> None: def test_telemetry_data_updates_correctly(app_instance: Any) -> None:
""" """
Tests that the _refresh_api_metrics method correctly updates Tests that the _refresh_api_metrics method correctly updates
the internal state for display by querying the ai_client. the internal state for display by querying the ai_client.
Verifies the boundary between GUI state and API state. Verifies the boundary between GUI state and API state.
@@ -43,6 +44,7 @@ def test_telemetry_data_updates_correctly(app_instance: Any) -> None:
def test_performance_history_updates(app_instance: Any) -> None: def test_performance_history_updates(app_instance: Any) -> None:
""" """
Verify the data structure that feeds the sparkline. Verify the data structure that feeds the sparkline.
This ensures that the rolling buffer for performance telemetry maintains This ensures that the rolling buffer for performance telemetry maintains
the correct size and default initialization to prevent GUI rendering crashes. the correct size and default initialization to prevent GUI rendering crashes.
@@ -54,6 +56,7 @@ def test_performance_history_updates(app_instance: Any) -> None:
def test_gui_updates_on_event(app_instance: App) -> None: def test_gui_updates_on_event(app_instance: App) -> None:
""" """
Verifies that when an API event is received (e.g. from ai_client), Verifies that when an API event is received (e.g. from ai_client),
the _on_api_event handler correctly updates internal metrics and the _on_api_event handler correctly updates internal metrics and
queues the update to be processed by the GUI event loop. queues the update to be processed by the GUI event loop.
+1
View File
@@ -6,6 +6,7 @@ from src.api_hook_client import ApiHookClient
async def test_mma_track_lifecycle_simulation(): async def test_mma_track_lifecycle_simulation():
""" """
This test simulates the sequence of API calls an external orchestrator This test simulates the sequence of API calls an external orchestrator
would make to manage an MMA track lifecycle via the Hook API. would make to manage an MMA track lifecycle via the Hook API.
It verifies that ApiHookClient correctly routes requests to the It verifies that ApiHookClient correctly routes requests to the
+2
View File
@@ -10,6 +10,7 @@ from src import ai_client
async def test_headless_verification_full_run(vlogger) -> None: async def test_headless_verification_full_run(vlogger) -> None:
""" """
1. Initialize a ConductorEngine with a Track containing multiple dependent Tickets. 1. Initialize a ConductorEngine with a Track containing multiple dependent Tickets.
2. Simulate a full execution run using engine.run(). 2. Simulate a full execution run using engine.run().
3. Mock ai_client.send to simulate successful tool calls and final responses. 3. Mock ai_client.send to simulate successful tool calls and final responses.
@@ -49,6 +50,7 @@ async def test_headless_verification_full_run(vlogger) -> None:
async def test_headless_verification_error_and_qa_interceptor(vlogger) -> None: async def test_headless_verification_error_and_qa_interceptor(vlogger) -> None:
""" """
5. Simulate a shell error and verify that the Tier 4 QA interceptor is triggered 5. Simulate a shell error and verify that the Tier 4 QA interceptor is triggered
and its summary is injected into the worker's history for the next retry. and its summary is injected into the worker's history for the next retry.
""" """
+4
View File
@@ -12,6 +12,7 @@ from src.gui_2 import App
def test_new_hubs_defined_in_show_windows(mock_app: App) -> None: def test_new_hubs_defined_in_show_windows(mock_app: App) -> None:
""" """
Verifies that the new consolidated Hub windows are defined in the App's show_windows. Verifies that the new consolidated Hub windows are defined in the App's show_windows.
This ensures they will be available in the 'Windows' menu. This ensures they will be available in the 'Windows' menu.
""" """
@@ -27,6 +28,7 @@ def test_new_hubs_defined_in_show_windows(mock_app: App) -> None:
def test_old_windows_removed_from_gui2(app_instance_simple: Any) -> None: def test_old_windows_removed_from_gui2(app_instance_simple: Any) -> None:
""" """
Verifies that the old fragmented windows are removed or renamed. Verifies that the old fragmented windows are removed or renamed.
""" """
old_tags = [ old_tags = [
@@ -54,6 +56,7 @@ def app_instance_simple() -> Any:
def test_hub_windows_exist_in_gui2(app_instance_simple: Any) -> None: def test_hub_windows_exist_in_gui2(app_instance_simple: Any) -> None:
""" """
Verifies that the new Hub windows are present in the show_windows dictionary. Verifies that the new Hub windows are present in the show_windows dictionary.
""" """
hubs = ["Project Settings", "AI Settings", "Discussion Hub", "Operations Hub"] hubs = ["Project Settings", "AI Settings", "Discussion Hub", "Operations Hub"]
@@ -63,6 +66,7 @@ def test_hub_windows_exist_in_gui2(app_instance_simple: Any) -> None:
def test_indicators_logic_exists(app_instance_simple: Any) -> None: def test_indicators_logic_exists(app_instance_simple: Any) -> None:
""" """
Verifies that the status indicators logic exists in the App. Verifies that the status indicators logic exists in the App.
""" """
assert hasattr(app_instance_simple, 'ai_status') assert hasattr(app_instance_simple, 'ai_status')
+2
View File
@@ -14,6 +14,7 @@ from src.api_hook_client import ApiHookClient
def test_user_request_integration_flow(mock_app: App) -> None: def test_user_request_integration_flow(mock_app: App) -> None:
""" """
Verifies that pushing a UserRequestEvent to the event_queue: Verifies that pushing a UserRequestEvent to the event_queue:
1. Triggers ai_client.send 1. Triggers ai_client.send
2. Results in a 'response' event back to the queue 2. Results in a 'response' event back to the queue
@@ -76,6 +77,7 @@ def test_user_request_integration_flow(mock_app: App) -> None:
def test_user_request_error_handling(mock_app: App) -> None: def test_user_request_error_handling(mock_app: App) -> None:
""" """
Verifies that if ai_client.send raises an exception, the UI is updated with the error state. Verifies that if ai_client.send raises an exception, the UI is updated with the error state.
""" """
app = mock_app app = mock_app
+2
View File
@@ -16,6 +16,7 @@ from src.api_hook_client import ApiHookClient
def wait_for_value(client, field, expected, timeout=10): def wait_for_value(client, field, expected, timeout=10):
""" """
Helper to poll the GUI state until a field matches the expected value. Helper to poll the GUI state until a field matches the expected value.
""" """
start = time.time() start = time.time()
@@ -31,6 +32,7 @@ def wait_for_value(client, field, expected, timeout=10):
def test_full_live_workflow(live_gui) -> None: def test_full_live_workflow(live_gui) -> None:
""" """
Integration test that drives the GUI through a full workflow. Integration test that drives the GUI through a full workflow.
ANTI-SIMPLIFICATION: Asserts exact AI behavior, thinking state tracking, ANTI-SIMPLIFICATION: Asserts exact AI behavior, thinking state tracking,
and response logging in discussion history. and response logging in discussion history.
+2
View File
@@ -11,6 +11,7 @@ from src import api_hook_client
def _poll_mma_status(client, timeout, condition, label): def _poll_mma_status(client, timeout, condition, label):
""" """
Poll get_mma_status() until condition(status) is True or timeout. Poll get_mma_status() until condition(status) is True or timeout.
[C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow] [C: tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow]
""" """
@@ -28,6 +29,7 @@ def _poll_mma_status(client, timeout, condition, label):
def test_mma_concurrent_tracks_execution(live_gui) -> None: def test_mma_concurrent_tracks_execution(live_gui) -> None:
""" """
Stress test for concurrent MMA track execution. Stress test for concurrent MMA track execution.
Verifies that starting multiple tracks simultaneously doesn't cause crashes Verifies that starting multiple tracks simultaneously doesn't cause crashes
and that workers from both tracks are processed. and that workers from both tracks are processed.
@@ -25,6 +25,7 @@ def _poll_mma_workers(client: api_hook_client.ApiHookClient, timeout: int, condi
def test_mma_concurrent_tracks_stress(live_gui) -> None: def test_mma_concurrent_tracks_stress(live_gui) -> None:
""" """
Stress test: Start two tracks concurrently and verify they both progress Stress test: Start two tracks concurrently and verify they both progress
without crashing the GUI or losing state. without crashing the GUI or losing state.
""" """
+9
View File
@@ -3,6 +3,7 @@ from src.models import Ticket, Track, WorkerContext
def test_ticket_instantiation() -> None: def test_ticket_instantiation() -> None:
""" """
Verifies that a Ticket can be instantiated with its required fields: Verifies that a Ticket can be instantiated with its required fields:
id, description, status, assigned_to. id, description, status, assigned_to.
""" """
@@ -25,6 +26,7 @@ def test_ticket_instantiation() -> None:
def test_ticket_with_dependencies() -> None: def test_ticket_with_dependencies() -> None:
""" """
Verifies that a Ticket can store dependencies. Verifies that a Ticket can store dependencies.
""" """
ticket = Ticket( ticket = Ticket(
@@ -39,6 +41,7 @@ def test_ticket_with_dependencies() -> None:
def test_track_instantiation() -> None: def test_track_instantiation() -> None:
""" """
Verifies that a Track can be instantiated with its required fields: Verifies that a Track can be instantiated with its required fields:
id, description, and a list of Tickets. id, description, and a list of Tickets.
""" """
@@ -61,6 +64,7 @@ def test_track_instantiation() -> None:
def test_track_can_handle_empty_tickets() -> None: def test_track_can_handle_empty_tickets() -> None:
""" """
Verifies that a Track can be instantiated with an empty list of tickets. Verifies that a Track can be instantiated with an empty list of tickets.
""" """
track = Track(id="TRACK-2", description="Empty Track", tickets=[]) track = Track(id="TRACK-2", description="Empty Track", tickets=[])
@@ -69,6 +73,7 @@ def test_track_can_handle_empty_tickets() -> None:
def test_worker_context_instantiation() -> None: def test_worker_context_instantiation() -> None:
""" """
Verifies that a WorkerContext can be instantiated with ticket_id, Verifies that a WorkerContext can be instantiated with ticket_id,
model_name, and messages. model_name, and messages.
""" """
@@ -90,6 +95,7 @@ def test_worker_context_instantiation() -> None:
def test_ticket_mark_blocked() -> None: def test_ticket_mark_blocked() -> None:
""" """
Verifies that ticket.mark_blocked(reason) sets the status to 'blocked'. Verifies that ticket.mark_blocked(reason) sets the status to 'blocked'.
Note: The reason field might need to be added to the Ticket class. Note: The reason field might need to be added to the Ticket class.
""" """
@@ -100,6 +106,7 @@ def test_ticket_mark_blocked() -> None:
def test_ticket_mark_complete() -> None: def test_ticket_mark_complete() -> None:
""" """
Verifies that ticket.mark_complete() sets the status to 'completed'. Verifies that ticket.mark_complete() sets the status to 'completed'.
""" """
ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="a") ticket = Ticket(id="T1", description="Task 1", status="todo", assigned_to="a")
@@ -109,6 +116,7 @@ def test_ticket_mark_complete() -> None:
def test_track_get_executable_tickets() -> None: def test_track_get_executable_tickets() -> None:
""" """
Verifies that track.get_executable_tickets() returns only 'todo' tickets Verifies that track.get_executable_tickets() returns only 'todo' tickets
whose dependencies are all 'completed'. whose dependencies are all 'completed'.
""" """
@@ -134,6 +142,7 @@ def test_track_get_executable_tickets() -> None:
def test_track_get_executable_tickets_complex() -> None: def test_track_get_executable_tickets_complex() -> None:
""" """
Verifies executable tickets with complex dependency chains. Verifies executable tickets with complex dependency chains.
Chain: T1 (comp) -> T2 (todo) -> T3 (todo) Chain: T1 (comp) -> T2 (todo) -> T3 (todo)
T4 (comp) -> T3 T4 (comp) -> T3
+1
View File
@@ -24,6 +24,7 @@ def _poll_mma_status(client: api_hook_client.ApiHookClient, timeout: int, condit
def test_mma_step_mode_approval_flow(live_gui) -> None: def test_mma_step_mode_approval_flow(live_gui) -> None:
""" """
Verify that we can manually approve a ticket in Step Mode and it proceeds. Verify that we can manually approve a ticket in Step Mode and it proceeds.
""" """
client = api_hook_client.ApiHookClient() client = api_hook_client.ApiHookClient()
+2
View File
@@ -13,6 +13,7 @@ from src import api_hook_client
def test_patch_modal_appears_on_trigger(live_gui) -> None: def test_patch_modal_appears_on_trigger(live_gui) -> None:
""" """
Test that triggering a patch shows the modal in the GUI. Test that triggering a patch shows the modal in the GUI.
Uses live_gui fixture to start the GUI with test hooks enabled. Uses live_gui fixture to start the GUI with test hooks enabled.
""" """
@@ -51,6 +52,7 @@ def test_patch_modal_appears_on_trigger(live_gui) -> None:
def test_patch_apply_modal_workflow(live_gui) -> None: def test_patch_apply_modal_workflow(live_gui) -> None:
""" """
Test the full patch apply workflow: trigger -> apply -> verify modal closes. Test the full patch apply workflow: trigger -> apply -> verify modal closes.
""" """
proc, _ = live_gui proc, _ = live_gui
+1
View File
@@ -25,6 +25,7 @@ def mock_project():
def test_rag_integration(mock_project): def test_rag_integration(mock_project):
""" """
Integration test verifying the flow from AppController through RAGEngine to ai_client. Integration test verifying the flow from AppController through RAGEngine to ai_client.
""" """
# 1. Initializes a mock project and AppController. # 1. Initializes a mock project and AppController.
+1
View File
@@ -10,6 +10,7 @@ class TestRunWorkerLifecycleAbort(unittest.TestCase):
def test_run_worker_lifecycle_returns_early_on_abort(self): def test_run_worker_lifecycle_returns_early_on_abort(self):
""" """
Test that run_worker_lifecycle returns early and marks ticket as 'killed' Test that run_worker_lifecycle returns early and marks ticket as 'killed'
if the abort event is set for the ticket. if the abort event is set for the ticket.
""" """
+1
View File
@@ -13,6 +13,7 @@ from src.gui_2 import App
def test_selectable_label_stability(live_gui) -> None: def test_selectable_label_stability(live_gui) -> None:
""" """
Verifies that the application starts correctly with --enable-test-hooks Verifies that the application starts correctly with --enable-test-hooks
and that the selectable label infrastructure is present and stable. and that the selectable label infrastructure is present and stable.
""" """
+1
View File
@@ -16,6 +16,7 @@ from simulation.sim_ai_settings import AISettingsSimulation
def test_ai_settings_simulation_run() -> None: def test_ai_settings_simulation_run() -> None:
""" """
Verifies that AISettingsSimulation correctly cycles through models Verifies that AISettingsSimulation correctly cycles through models
to test the settings UI components. to test the settings UI components.
""" """
+2
View File
@@ -16,6 +16,7 @@ from simulation.sim_base import BaseSimulation
def test_base_simulation_init() -> None: def test_base_simulation_init() -> None:
""" """
Verifies that the BaseSimulation initializes the ApiHookClient correctly. Verifies that the BaseSimulation initializes the ApiHookClient correctly.
""" """
with patch('simulation.sim_base.ApiHookClient') as mock_client_class: with patch('simulation.sim_base.ApiHookClient') as mock_client_class:
@@ -29,6 +30,7 @@ def test_base_simulation_init() -> None:
def test_base_simulation_setup() -> None: def test_base_simulation_setup() -> None:
""" """
Verifies that the setup routine correctly resets the GUI state Verifies that the setup routine correctly resets the GUI state
and initializes a clean temporary project for simulation. and initializes a clean temporary project for simulation.
""" """
+1
View File
@@ -16,6 +16,7 @@ from simulation.sim_context import ContextSimulation
def test_context_simulation_run() -> None: def test_context_simulation_run() -> None:
""" """
Verifies that the ContextSimulation runs the correct sequence of user actions: Verifies that the ContextSimulation runs the correct sequence of user actions:
discussion switching, context building (md_only), and history truncation. discussion switching, context building (md_only), and history truncation.
""" """
+1
View File
@@ -16,6 +16,7 @@ from simulation.sim_execution import ExecutionSimulation
def test_execution_simulation_run() -> None: def test_execution_simulation_run() -> None:
""" """
Verifies that ExecutionSimulation handles script confirmation modals. Verifies that ExecutionSimulation handles script confirmation modals.
Ensures that it waits for the modal and clicks the approve button. Ensures that it waits for the modal and clicks the approve button.
""" """
+1
View File
@@ -16,6 +16,7 @@ from simulation.sim_tools import ToolsSimulation
def test_tools_simulation_run() -> None: def test_tools_simulation_run() -> None:
""" """
Verifies that ToolsSimulation requests specific tool executions Verifies that ToolsSimulation requests specific tool executions
and verifies they appear in the resulting session history. and verifies they appear in the resulting session history.
""" """
+1
View File
@@ -7,6 +7,7 @@ import os
def test_system_prompt_sim(live_gui): def test_system_prompt_sim(live_gui):
""" """
Simulation test for system prompt settings. Simulation test for system prompt settings.
1. Wait for server. 1. Wait for server.
2. Verify initial state. 2. Verify initial state.
+1
View File
@@ -62,6 +62,7 @@ def test_run_powershell_optional_qa_callback() -> None:
def test_end_to_end_tier4_integration(vlogger) -> None: def test_end_to_end_tier4_integration(vlogger) -> None:
""" """
1. Start a task that triggers a tool failure. 1. Start a task that triggers a tool failure.
2. Ensure Tier 4 QA analysis is run. 2. Ensure Tier 4 QA analysis is run.
3. Verify the analysis is merged into the next turn's prompt. 3. Verify the analysis is merged into the next turn's prompt.
+1
View File
@@ -8,6 +8,7 @@ from src.project_manager import save_track_state, load_track_state
def test_track_state_persistence(tmp_path) -> None: def test_track_state_persistence(tmp_path) -> None:
""" """
Tests saving and loading a TrackState object to/from a TOML file. Tests saving and loading a TrackState object to/from a TOML file.
1. Create a TrackState object with sample metadata, discussion, and tasks. 1. Create a TrackState object with sample metadata, discussion, and tasks.
2. Call save_track_state('test_track', state, base_dir). 2. Call save_track_state('test_track', state, base_dir).
+1
View File
@@ -4,6 +4,7 @@ from tree_sitter import Language, Parser
def test_tree_sitter_python_setup() -> None: def test_tree_sitter_python_setup() -> None:
""" """
Verifies that tree-sitter and tree-sitter-python are correctly installed Verifies that tree-sitter and tree-sitter-python are correctly installed
and can parse a simple Python function string. and can parse a simple Python function string.
""" """
+1
View File
@@ -56,6 +56,7 @@ def _poll(client: api_hook_client.ApiHookClient, timeout: int, condition, label:
def test_mma_complete_lifecycle(live_gui) -> None: def test_mma_complete_lifecycle(live_gui) -> None:
""" """
End-to-end MMA lifecycle using real Gemini API (gemini-2.5-flash-lite). End-to-end MMA lifecycle using real Gemini API (gemini-2.5-flash-lite).
Incorporates frame-sync sleeps and explicit state-transition waits per Incorporates frame-sync sleeps and explicit state-transition waits per
simulation_hardening_20260301 spec (Issues 2 & 3). simulation_hardening_20260301 spec (Issues 2 & 3).
+1
View File
@@ -14,6 +14,7 @@ from src import api_hook_client
def test_workspace_profiles_restoration(live_gui): def test_workspace_profiles_restoration(live_gui):
""" """
Verifies that workspace profiles can save and restore UI state. Verifies that workspace profiles can save and restore UI state.
1. Sets a field (ui_separate_tier1) to True. 1. Sets a field (ui_separate_tier1) to True.
2. Saves a workspace profile. 2. Saves a workspace profile.