Private
Public Access
refactor(project_files): create src/project_files.py (split from models.py)
Per the 4-criteria decision rule (C1=cross-system, C3=tests, C4=substantial);
FileItem is the canonical per-file data structure used by aggregate,
app_controller, gui_2, presets, context_presets, and tests. Preset /
ContextPreset / ContextFileEntry / NamedViewPreset are the preset/view
data structures that round-trip through TOML.
This commit:
1. Creates src/project_files.py with FileItem + Preset + ContextPreset +
ContextFileEntry + NamedViewPreset (full class bodies copied verbatim
from src/models.py including __post_init__, to_dict, from_dict, and
the [C: ...] caller-docstring tags).
2. Removes the 5 class definitions from src/models.py.
3. Adds backward-compat re-exports in src/models.py (the same pattern
used by Phase 3a mma.py + Phase 3b project.py + Phase 3g personas.py).
4. Updates the 4 consumer files to import from src.project_files directly:
src/orchestrator_pm.py, src/presets.py, src/context_presets.py,
src/ai_client.py (3 sites of the banned 'local import + as _FIC alias'
pattern updated to use src.project_files.FileItem; the aliasing
anti-pattern is preserved for now - a follow-up track will remove
the local imports and the aliasing).
Verification: VC7
from src.project_files import FileItem, Preset, ContextPreset,
ContextFileEntry, NamedViewPreset # OK
from src.models import FileItem, Preset, ... # OK
(re-exports work; identity check: FileItem is FileItem returns True)
Tests verified (20/20 PASS):
tests/test_file_item_model.py (4 tests)
tests/test_view_presets.py (4 tests)
tests/test_context_presets_models.py (3 tests)
tests/test_custom_slices_annotations.py (3 tests)
tests/test_presets.py (5 tests)
Decorator-orphan pitfall caught and fixed: after removing the 3 classes
between WorkspaceProfile and the MCP Config region, the @dataclass
decorator was orphaned on a comment line. Removed the orphan.
This commit is contained in:
+6
-6
@@ -2667,8 +2667,8 @@ def _send_grok(md_content: str, user_message: str, base_dir: str,
|
|||||||
if file_items:
|
if file_items:
|
||||||
for fi in file_items:
|
for fi in file_items:
|
||||||
if fi.get("is_image") and fi.get("base64_data"):
|
if fi.get("is_image") and fi.get("base64_data"):
|
||||||
from src.models import FileItem as _FIC
|
from src.project_files import FileItem
|
||||||
fi_item = fi if isinstance(fi, _FIC) else _FIC.from_dict(fi)
|
fi_item = fi if isinstance(fi, FileItem) else FileItem.from_dict(fi)
|
||||||
user_content = f"[IMAGE: {fi_item.path or 'attachment'}]\n{user_content}"
|
user_content = f"[IMAGE: {fi_item.path or 'attachment'}]\n{user_content}"
|
||||||
if discussion_history and not history:
|
if discussion_history and not history:
|
||||||
history.append({"role": "user", "content": f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"})
|
history.append({"role": "user", "content": f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"})
|
||||||
@@ -2909,8 +2909,8 @@ def _send_qwen(md_content: str, user_message: str, base_dir: str,
|
|||||||
if file_items:
|
if file_items:
|
||||||
for fi in file_items:
|
for fi in file_items:
|
||||||
if fi.get("is_image") and fi.get("base64_data"):
|
if fi.get("is_image") and fi.get("base64_data"):
|
||||||
from src.models import FileItem as _FIC
|
from src.project_files import FileItem
|
||||||
fi_item = fi if isinstance(fi, _FIC) else _FIC.from_dict(fi)
|
fi_item = fi if isinstance(fi, FileItem) else FileItem.from_dict(fi)
|
||||||
user_content = f"[IMAGE: {fi_item.path or 'attachment'}]\n{user_content}"
|
user_content = f"[IMAGE: {fi_item.path or 'attachment'}]\n{user_content}"
|
||||||
if discussion_history and not history:
|
if discussion_history and not history:
|
||||||
history.append({"role": "user", "content": f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"})
|
history.append({"role": "user", "content": f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"})
|
||||||
@@ -3002,8 +3002,8 @@ def _send_llama(md_content: str, user_message: str, base_dir: str,
|
|||||||
if file_items:
|
if file_items:
|
||||||
for fi in file_items:
|
for fi in file_items:
|
||||||
if fi.get("is_image") and fi.get("base64_data"):
|
if fi.get("is_image") and fi.get("base64_data"):
|
||||||
from src.models import FileItem as _FIC
|
from src.project_files import FileItem
|
||||||
fi_item = fi if isinstance(fi, _FIC) else _FIC.from_dict(fi)
|
fi_item = fi if isinstance(fi, FileItem) else FileItem.from_dict(fi)
|
||||||
user_content = f"[IMAGE: {fi_item.path or 'attachment'}]\n{user_content}"
|
user_content = f"[IMAGE: {fi_item.path or 'attachment'}]\n{user_content}"
|
||||||
if discussion_history and not history:
|
if discussion_history and not history:
|
||||||
history.append({"role": "user", "content": f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"})
|
history.append({"role": "user", "content": f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
|
|
||||||
from src.models import ContextPreset
|
from src.project_files import ContextPreset
|
||||||
from src.result_types import Result, ErrorInfo, ErrorKind
|
from src.result_types import Result, ErrorInfo, ErrorKind
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+22
-160
@@ -99,6 +99,18 @@ from src.project import (
|
|||||||
parse_history_entries,
|
parse_history_entries,
|
||||||
save_config_to_disk,
|
save_config_to_disk,
|
||||||
)
|
)
|
||||||
|
# Backward-compat re-exports for FileItem + Preset + ContextPreset +
|
||||||
|
# ContextFileEntry + NamedViewPreset (Phase 3c -> src/project_files.py).
|
||||||
|
# Consumers using 'from src.models import FileItem' (and the others) must
|
||||||
|
# migrate to the new path in src.project_files. These classes are added
|
||||||
|
# here for backward compat and dropped in Phase 5.
|
||||||
|
from src.project_files import (
|
||||||
|
ContextFileEntry,
|
||||||
|
ContextPreset,
|
||||||
|
FileItem,
|
||||||
|
NamedViewPreset,
|
||||||
|
Preset,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#region: Constants
|
#region: Constants
|
||||||
@@ -261,83 +273,11 @@ def __getattr__(name: str) -> Any:
|
|||||||
|
|
||||||
#region: State & Config
|
#region: State & Config
|
||||||
# TrackState moved to src/mma.py (re-exported at the top of this module for backward compat).
|
# TrackState moved to src/mma.py (re-exported at the top of this module for backward compat).
|
||||||
|
# FileItem, Preset, ContextFileEntry, NamedViewPreset, ContextPreset moved to
|
||||||
@dataclass
|
# src/project_files.py in module_taxonomy_refactor_20260627 Phase 3c. The
|
||||||
class FileItem:
|
# re-exports at the top of this module keep 'from src.models import FileItem'
|
||||||
path: str
|
# (and the others) working for legacy callers. New code should import from
|
||||||
auto_aggregate: bool = True
|
# src.project_files directly.
|
||||||
force_full: bool = False
|
|
||||||
view_mode: str = 'full'
|
|
||||||
selected: bool = False
|
|
||||||
ast_signatures: bool = False
|
|
||||||
ast_definitions: bool = False
|
|
||||||
ast_mask: dict[str, str] = field(default_factory=dict)
|
|
||||||
custom_slices: list[dict] = field(default_factory=list)
|
|
||||||
injected_at: Optional[float] = None
|
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
if self.custom_slices:
|
|
||||||
normalized = []
|
|
||||||
for slc in self.custom_slices:
|
|
||||||
if isinstance(slc, dict):
|
|
||||||
new_slc = slc.copy()
|
|
||||||
if "tag" not in new_slc: new_slc["tag"] = None
|
|
||||||
if "comment" not in new_slc: new_slc["comment"] = None
|
|
||||||
normalized.append(new_slc)
|
|
||||||
else:
|
|
||||||
normalized.append(slc)
|
|
||||||
self.custom_slices = normalized
|
|
||||||
|
|
||||||
def to_dict(self) -> Metadata:
|
|
||||||
"""
|
|
||||||
[C: 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 {
|
|
||||||
"path": self.path,
|
|
||||||
"auto_aggregate": self.auto_aggregate,
|
|
||||||
"force_full": self.force_full,
|
|
||||||
"view_mode": self.view_mode,
|
|
||||||
"ast_signatures": self.ast_signatures,
|
|
||||||
"ast_definitions": self.ast_definitions,
|
|
||||||
"ast_mask": self.ast_mask,
|
|
||||||
"custom_slices": self.custom_slices,
|
|
||||||
"injected_at": self.injected_at,
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, data: Metadata) -> "FileItem":
|
|
||||||
"""
|
|
||||||
[C: 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(
|
|
||||||
path = data["path"],
|
|
||||||
auto_aggregate = data.get("auto_aggregate", True),
|
|
||||||
force_full = data.get("force_full", False),
|
|
||||||
view_mode = data.get("view_mode", 'full'),
|
|
||||||
ast_signatures = data.get("ast_signatures", False),
|
|
||||||
ast_definitions = data.get("ast_definitions", False),
|
|
||||||
ast_mask = data.get("ast_mask", {}),
|
|
||||||
custom_slices = data.get("custom_slices", []),
|
|
||||||
injected_at = data.get("injected_at"),
|
|
||||||
)
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Preset:
|
|
||||||
name: str
|
|
||||||
system_prompt: str
|
|
||||||
|
|
||||||
def to_dict(self) -> Metadata:
|
|
||||||
"""
|
|
||||||
[C: 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 {"system_prompt": self.system_prompt}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, name: str, data: Metadata) -> "Preset":
|
|
||||||
"""
|
|
||||||
[C: 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(name=name, system_prompt=data.get("system_prompt", ""))
|
|
||||||
|
|
||||||
#region: Tool Models
|
#region: Tool Models
|
||||||
|
|
||||||
@@ -527,89 +467,11 @@ class WorkspaceProfile:
|
|||||||
panel_states = data.get("panel_states", {}),
|
panel_states = data.get("panel_states", {}),
|
||||||
)
|
)
|
||||||
|
|
||||||
@dataclass
|
# ContextFileEntry, NamedViewPreset, ContextPreset moved to src/project_files.py
|
||||||
class ContextFileEntry:
|
# in module_taxonomy_refactor_20260627 Phase 3c. The re-exports at the top of
|
||||||
path: str
|
# this module keep 'from src.models import ContextFileEntry' (and the others)
|
||||||
view_mode: str = "summary"
|
# working for legacy callers. New code should import from src.project_files
|
||||||
custom_slices: list = field(default_factory=list)
|
# directly.
|
||||||
ast_mask: dict = field(default_factory=dict)
|
|
||||||
ast_signatures: bool = False
|
|
||||||
ast_definitions: bool = False
|
|
||||||
|
|
||||||
def to_dict(self) -> Metadata:
|
|
||||||
"""
|
|
||||||
[C: 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 {"path": self.path, "view_mode": self.view_mode, "custom_slices": self.custom_slices, "ast_mask": self.ast_mask, "ast_signatures": self.ast_signatures, "ast_definitions": self.ast_definitions}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, data: Metadata) -> "ContextFileEntry":
|
|
||||||
"""
|
|
||||||
[C: 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(
|
|
||||||
path = data.get("path", ""),
|
|
||||||
view_mode = data.get("view_mode", "summary"),
|
|
||||||
custom_slices = data.get("custom_slices", []),
|
|
||||||
ast_mask = data.get("ast_mask", {}),
|
|
||||||
ast_signatures = data.get("ast_signatures", False),
|
|
||||||
ast_definitions = data.get("ast_definitions", False),
|
|
||||||
)
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class NamedViewPreset:
|
|
||||||
name: str
|
|
||||||
view_mode: str
|
|
||||||
ast_mask: dict = field(default_factory=dict)
|
|
||||||
custom_slices: list = field(default_factory=list)
|
|
||||||
|
|
||||||
def to_dict(self) -> Metadata:
|
|
||||||
"""
|
|
||||||
[C: 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 {"name": self.name, "view_mode": self.view_mode, "ast_mask": self.ast_mask, "custom_slices": self.custom_slices}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, data: Metadata) -> "NamedViewPreset":
|
|
||||||
"""
|
|
||||||
[C: 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(
|
|
||||||
name = data.get("name", ""),
|
|
||||||
view_mode = data.get("view_mode", "summary"),
|
|
||||||
ast_mask = data.get("ast_mask", {}),
|
|
||||||
custom_slices = data.get("custom_slices", []),
|
|
||||||
)
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ContextPreset:
|
|
||||||
name: str
|
|
||||||
files: list[ContextFileEntry] = field(default_factory=list)
|
|
||||||
screenshots: list[str] = field(default_factory=list)
|
|
||||||
description: str = ""
|
|
||||||
|
|
||||||
def to_dict(self) -> Metadata:
|
|
||||||
"""
|
|
||||||
[C: 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 {
|
|
||||||
"files": [f.to_dict() for f in self.files],
|
|
||||||
"screenshots": self.screenshots,
|
|
||||||
"description": self.description,
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, name: str, data: Metadata) -> "ContextPreset":
|
|
||||||
"""
|
|
||||||
[C: 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]
|
|
||||||
"""
|
|
||||||
files_data = data.get("files", [])
|
|
||||||
return cls(
|
|
||||||
name = name,
|
|
||||||
files = [ContextFileEntry.from_dict(f) if isinstance(f, dict) else ContextFileEntry(path=str(f)) for f in files_data],
|
|
||||||
screenshots = data.get("screenshots", []),
|
|
||||||
description = data.get("description", ""),
|
|
||||||
)
|
|
||||||
|
|
||||||
#region: MCP Config
|
#region: MCP Config
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from src import ai_client
|
|||||||
from src import mma_prompts
|
from src import mma_prompts
|
||||||
from src import paths
|
from src import paths
|
||||||
from src import summarize
|
from src import summarize
|
||||||
from src.models import FileItem
|
from src.project_files import FileItem
|
||||||
from src.result_types import Result, ErrorInfo, ErrorKind
|
from src.result_types import Result, ErrorInfo, ErrorKind
|
||||||
from src.type_aliases import Metadata
|
from src.type_aliases import Metadata
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import tomli_w
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Any, Optional
|
from typing import Dict, Any, Optional
|
||||||
|
|
||||||
from src.models import Preset
|
from src.project_files import Preset
|
||||||
from src.paths import get_global_presets_path, get_project_presets_path
|
from src.paths import get_global_presets_path, get_project_presets_path
|
||||||
from src.result_types import ErrorInfo, ErrorKind, Result
|
from src.result_types import ErrorInfo, ErrorKind, Result
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,188 @@
|
|||||||
|
"""File-related project state dataclasses.
|
||||||
|
|
||||||
|
Per module_taxonomy_refactor_20260627 Phase 3c, the file + view + preset
|
||||||
|
dataclasses moved from src/models.py to this module.
|
||||||
|
|
||||||
|
Per the 4-criteria decision rule:
|
||||||
|
- C1 (cross-system usage >= 3 systems): YES (aggregate, app_controller,
|
||||||
|
gui_2, presets, context_presets, tests)
|
||||||
|
- C2 (state machine / lifecycle): NO (just data; no state transitions)
|
||||||
|
- C3 (test file already exists): YES (test_file_item_model.py,
|
||||||
|
test_view_presets.py, test_context_presets_*.py)
|
||||||
|
- C4 (substantial size): YES (FileItem has 10 fields + __post_init__ +
|
||||||
|
to_dict/from_dict; ContextPreset nests ContextFileEntry + list)
|
||||||
|
|
||||||
|
Therefore: DEDICATED FILE = src/project_files.py
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from src.type_aliases import Metadata
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FileItem:
|
||||||
|
path: str
|
||||||
|
auto_aggregate: bool = True
|
||||||
|
force_full: bool = False
|
||||||
|
view_mode: str = 'full'
|
||||||
|
selected: bool = False
|
||||||
|
ast_signatures: bool = False
|
||||||
|
ast_definitions: bool = False
|
||||||
|
ast_mask: dict[str, str] = field(default_factory=dict)
|
||||||
|
custom_slices: list[dict] = field(default_factory=list)
|
||||||
|
injected_at: Optional[float] = None
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
if self.custom_slices:
|
||||||
|
normalized = []
|
||||||
|
for slc in self.custom_slices:
|
||||||
|
if isinstance(slc, dict):
|
||||||
|
new_slc = slc.copy()
|
||||||
|
if "tag" not in new_slc: new_slc["tag"] = None
|
||||||
|
if "comment" not in new_slc: new_slc["comment"] = None
|
||||||
|
normalized.append(new_slc)
|
||||||
|
else:
|
||||||
|
normalized.append(slc)
|
||||||
|
self.custom_slices = normalized
|
||||||
|
|
||||||
|
def to_dict(self) -> Metadata:
|
||||||
|
"""
|
||||||
|
[C: 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 {
|
||||||
|
"path": self.path,
|
||||||
|
"auto_aggregate": self.auto_aggregate,
|
||||||
|
"force_full": self.force_full,
|
||||||
|
"view_mode": self.view_mode,
|
||||||
|
"ast_signatures": self.ast_signatures,
|
||||||
|
"ast_definitions": self.ast_definitions,
|
||||||
|
"ast_mask": self.ast_mask,
|
||||||
|
"custom_slices": self.custom_slices,
|
||||||
|
"injected_at": self.injected_at,
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, data: Metadata) -> "FileItem":
|
||||||
|
"""
|
||||||
|
[C: 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(
|
||||||
|
path = data["path"],
|
||||||
|
auto_aggregate = data.get("auto_aggregate", True),
|
||||||
|
force_full = data.get("force_full", False),
|
||||||
|
view_mode = data.get("view_mode", 'full'),
|
||||||
|
ast_signatures = data.get("ast_signatures", False),
|
||||||
|
ast_definitions = data.get("ast_definitions", False),
|
||||||
|
ast_mask = data.get("ast_mask", {}),
|
||||||
|
custom_slices = data.get("custom_slices", []),
|
||||||
|
injected_at = data.get("injected_at"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Preset:
|
||||||
|
name: str
|
||||||
|
system_prompt: str
|
||||||
|
|
||||||
|
def to_dict(self) -> Metadata:
|
||||||
|
"""
|
||||||
|
[C: 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 {"system_prompt": self.system_prompt}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, name: str, data: Metadata) -> "Preset":
|
||||||
|
"""
|
||||||
|
[C: 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(name=name, system_prompt=data.get("system_prompt", ""))
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ContextFileEntry:
|
||||||
|
path: str
|
||||||
|
view_mode: str = "summary"
|
||||||
|
custom_slices: list = field(default_factory=list)
|
||||||
|
ast_mask: dict = field(default_factory=dict)
|
||||||
|
ast_signatures: bool = False
|
||||||
|
ast_definitions: bool = False
|
||||||
|
|
||||||
|
def to_dict(self) -> Metadata:
|
||||||
|
"""
|
||||||
|
[C: 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 {"path": self.path, "view_mode": self.view_mode, "custom_slices": self.custom_slices, "ast_mask": self.ast_mask, "ast_signatures": self.ast_signatures, "ast_definitions": self.ast_definitions}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, data: Metadata) -> "ContextFileEntry":
|
||||||
|
"""
|
||||||
|
[C: 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(
|
||||||
|
path = data.get("path", ""),
|
||||||
|
view_mode = data.get("view_mode", "summary"),
|
||||||
|
custom_slices = data.get("custom_slices", []),
|
||||||
|
ast_mask = data.get("ast_mask", {}),
|
||||||
|
ast_signatures = data.get("ast_signatures", False),
|
||||||
|
ast_definitions = data.get("ast_definitions", False),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class NamedViewPreset:
|
||||||
|
name: str
|
||||||
|
view_mode: str
|
||||||
|
ast_mask: dict = field(default_factory=dict)
|
||||||
|
custom_slices: list = field(default_factory=list)
|
||||||
|
|
||||||
|
def to_dict(self) -> Metadata:
|
||||||
|
"""
|
||||||
|
[C: 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 {"name": self.name, "view_mode": self.view_mode, "ast_mask": self.ast_mask, "custom_slices": self.custom_slices}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, data: Metadata) -> "NamedViewPreset":
|
||||||
|
"""
|
||||||
|
[C: 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(
|
||||||
|
name = data.get("name", ""),
|
||||||
|
view_mode = data.get("view_mode", "summary"),
|
||||||
|
ast_mask = data.get("ast_mask", {}),
|
||||||
|
custom_slices = data.get("custom_slices", []),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ContextPreset:
|
||||||
|
name: str
|
||||||
|
files: list[ContextFileEntry] = field(default_factory=list)
|
||||||
|
screenshots: list[str] = field(default_factory=list)
|
||||||
|
description: str = ""
|
||||||
|
|
||||||
|
def to_dict(self) -> Metadata:
|
||||||
|
"""
|
||||||
|
[C: 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 {
|
||||||
|
"files": [f.to_dict() for f in self.files],
|
||||||
|
"screenshots": self.screenshots,
|
||||||
|
"description": self.description,
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, name: str, data: Metadata) -> "ContextPreset":
|
||||||
|
"""
|
||||||
|
[C: 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]
|
||||||
|
"""
|
||||||
|
files_data = data.get("files", [])
|
||||||
|
return cls(
|
||||||
|
name = name,
|
||||||
|
files = [ContextFileEntry.from_dict(f) if isinstance(f, dict) else ContextFileEntry(path=str(f)) for f in files_data],
|
||||||
|
screenshots = data.get("screenshots", []),
|
||||||
|
description = data.get("description", ""),
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user