Hai bản tách song song của cùng một god-file cùng được giữ lại sau một lần
merge. Bản chết không ai import, và hai file trong đó còn không import nổi:
`graph_render.py` lấy `GraphQaMixin` không tồn tại, `task_actions.py` lấy
`ui.calendar_view` đã bị xoá.
Kèm theo 5 gói chỉ có `__init__.py` với docstring hứa những module chưa bao
giờ được tạo. Hai trong số đó (`adapters/qt/`, `infrastructure/platform/qt/`)
là vị trí đã bị bác bỏ có ghi lý do — `QtSchedulerClock` nằm ở
`infrastructure/qt/`, và lý do vì sao không đặt ở `platform/` vẫn còn nguyên
trong `infrastructure/qt/__init__.py`.
Không cổng nào bắt được đám này: file không ai import vẫn đúng chiều phụ
thuộc, vẫn sạch credential, vẫn dưới 400 dòng. Cổng O ở commit sau đi tìm
đúng khoảng trống đó.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
presentation/folder/
ai_edit_runner.py 325 một lượt AI sửa file, từ gửi tới xem trước
document_preview_manager.py 317 PDF/Word/Excel/PowerPoint/ảnh/HTML/mã
ai_file_editor_dialog.py 317 dựng panel AI + chọn model
code_editor.py 183 ô soạn mã, đánh số dòng, tô cú pháp
ai_output_writer.py 140 phần DUY NHẤT chạm vào file người dùng
image_model_picker.py 115 dò model sinh ảnh trên mọi provider
file_helpers.py 112 nhận dạng loại file + ngưỡng
workspace_file_tree.py 38 cây thư mục
ui/folder_tab.py 305 lắp ráp + retranslate
Plan ghi 3 file; khối lượng thật cần 8. Hai file tôi thêm ngoài dự kiến vì
đọc kỹ thì chúng là ranh giới thật:
* ai_output_writer.py — tách ra vì đây là phần duy nhất THẬT SỰ ghi đè file
của người dùng. Mọi thứ trước nó chỉ dựng bản xem trước. Ranh giới đó đáng
nhìn thấy trong cấu trúc thư mục.
* image_model_picker.py — chỗ duy nhất trong màn Thư mục biết tới nhiều
provider cùng lúc (nó gợi ý được model sinh ảnh của provider KHÁC cái đang
chọn).
Gom mọi hằng nhận dạng loại file (_IMAGE_SUFFIXES, _HAS_PDF, _MAX_EDIT_BYTES…)
về file_helpers.py: cả tám file trong gói đều hỏi tới, để rải ra thì thêm một
đuôi file phải sửa vài chỗ.
LẠI IMPORT LAZY THỤT LỀ: regex đổi mức tương đối của tôi chỉ khớp đầu dòng
nên bỏ sót import nằm trong thân hàm — 3 checker đỏ. Lần này tôi sửa một lượt
cho CẢ cây presentation/ thay vì riêng thư mục vừa tách; nó tìm ra thêm 3 file
ở scheduling cũng đang sai mà chưa nổ.
756 test xanh. 24/24 checker qua.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Team Hoa, EPIC R08 (UI/Application Separation) - Team Hoa scope only
(R08-T11 -> T14; R08-T01->T10 belong to Team Duy/Team Nam).
- R08-T11: ui/schedule_task_tab.py (795 lines) -> presentation/scheduling/
{kanban_board_widget,calendar_view_widget,ai_task_creator_dialog,
ai_task_import_dialog,run_history_dialog}.py + schedule_task_tab.py
shell. Kanban CRUD/drag-drop now goes through
application/scheduling/task_application_service.py (R07-T04) instead of
~30 lines of inline if/elif per drag target.
- R08-T12: ui/folder_tab.py (1587 lines, the largest of the four) ->
presentation/folder/{workspace_file_tree,document_preview_manager,
code_editor,office_document_renderer,ai_file_editor_dialog,
ai_edit_model_resolver,ai_edit_pipeline}.py + folder_tab.py shell.
Closes the R06-T05 loop: FileWorkspaceService existed since R06 with
zero production call sites (confirmed by grep); every plain-text write
(save/create/write_content) now goes through it, gaining path
containment and a Python-syntax warning the original code never had.
Pure helpers (_read_text, _is_probably_text, _pptx_available,
_split_code_block, _parse_ai_output) moved to
application/workspaces/{file_preview_helpers,ai_edit_output}.py.
- R08-T13: ui/dashboard_tab.py (437 lines) -> presentation/dashboard/
{token_usage_card_widget,usage_chart_widget,habits_widget}.py +
dashboard_tab.py shell, backed by a new
application/monitoring/dashboard_query_service.py (pricing/period/
summary queries the three widgets used to each recompute separately).
Directory-ownership note left in the checklist for Team Nam.
- R08-T14: ui/structure_graph_view.py (1035 lines) ->
presentation/graph/{graph_scene_items,graph_renderer,
graph_messages_view,graph_qa_widget}.py + structure_graph_view.py
shell. Extraction helpers (_pdf_to_markdown, _extract_file_contents)
moved to application/workspaces/graph_index_service.py (pure Python).
Renderer and Q&A panel talk only through signals
(node_selected/graph_rendered/raw_json_ready/project_changed) - neither
imports the other.
- presentation/shared/web_engine_support.py: HAS_WEB_ENGINE, previously
duplicated (folder_tab imported it FROM structure_graph_view.py) - now
one shared flag instead of one screen importing another screen's module.
All four old ui/*.py files deleted; app.py and ui/workspace_tab.py updated
to the new import paths (each god-file only had 1-2 real construction
sites, so import sites were updated directly rather than kept as a
strangler-fig shim - unlike core/tools.py at R05, which had dozens).
pytest: 377 pass (+94 vs the R07 baseline of 328; same 4 pre-existing
failures as the R05/R06 baseline, unrelated to this work).
scripts/check_imports.py: PASS. python -c "import cowork_local.app": OK.
Every new file < 400 lines (largest: graph_renderer.py, 391).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>