feat(workspace): mỗi thư mục làm việc chỉ thuộc về một project
CI / test (pull_request) Canceled after 0s
CI / test (pull_request) Canceled after 0s
Thư mục làm việc vừa là sandbox (agent chỉ đọc/ghi bên trong nó) vừa là kho kiến thức chung của project (file ở gốc được mọi đoạn chat tự đọc). Hai project trỏ vào cùng một thư mục là đọc lẫn dữ liệu của nhau và ghi đè lên nhau — đúng điều docstring đầu core/projects.py nói sandbox sinh ra để ngăn, nhưng không có chỗ nào thực thi: cả ba nơi đặt thư mục đều gán thẳng output_dir rồi lưu. Thêm core.projects.folder_conflict: so theo workspace_dir() chứ không theo output_dir (project chưa đặt thư mục riêng vẫn đang chiếm thư mục quản lý sẵn), chuẩn hoá đường dẫn bằng expanduser + abspath + normcase, và coi thư mục lồng nhau là trùng — đứng ở thư mục cha vẫn với tới được file của project con. Chặn tại cả ba nơi ghi output_dir: nút Đổi ở màn Project, thư mục mirror cloud, và nút chọn thư mục trong tab Cowork. Chặn lúc CHỌN chứ không lúc Lưu, vì nút Lưu chỉ ghi tên/mô tả/chỉ dẫn — chặn ở đó sẽ khoá luôn việc đổi tên một project lỡ đang trùng thư mục. Dữ liệu đã trùng sẵn không bị tự sửa: có nhãn cảnh báo ngay dưới ô Thư mục làm việc, nói rõ trùng với project nào, để người dùng tự quyết. Luật ở module riêng (presentation/workspace/project_folder_rules.py) vì nhét vào project_editing.py sẽ đẩy file đó lên 435 dòng, vượt trần 400 của scripts/check_loc.py. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+6
-1
@@ -27,13 +27,14 @@ from PySide6.QtWidgets import (
|
||||
|
||||
from ..i18n import on_language_changed, tr
|
||||
from ..presentation.workspace.project_editing import ProjectEditingMixin, ProjectRow
|
||||
from ..presentation.workspace.project_folder_rules import ProjectFolderRuleMixin, folder_taken_blocked
|
||||
from ..state import AppContext
|
||||
from .icons import collapse_left_icon, icon
|
||||
from .osutil import open_folder
|
||||
from .widgets import CollapseStrip
|
||||
|
||||
|
||||
class WorkspaceTab(ProjectEditingMixin, QWidget):
|
||||
class WorkspaceTab(ProjectEditingMixin, ProjectFolderRuleMixin, QWidget):
|
||||
"""Trang chủ Workspace: cột project, cột lịch sử, và 5 sub-tab
|
||||
(Dự án · Cowork · Co4E · Thư mục · GraphRAG).
|
||||
|
||||
@@ -941,6 +942,8 @@ class WorkspaceTab(ProjectEditingMixin, QWidget):
|
||||
self, tr("workspace.browse_tooltip"), str(project.workspace_dir()))
|
||||
if not chosen:
|
||||
return
|
||||
if folder_taken_blocked(self, chosen, pid):
|
||||
return
|
||||
project.output_dir = chosen
|
||||
save_project(project)
|
||||
self.folder_lbl.setText(chosen)
|
||||
@@ -984,6 +987,8 @@ class WorkspaceTab(ProjectEditingMixin, QWidget):
|
||||
if not cloud_source:
|
||||
return
|
||||
local_dir = WORKSPACES_DIR / project.project_id / "_cloud_mirror"
|
||||
if folder_taken_blocked(self, str(local_dir), pid):
|
||||
return
|
||||
self._cloud_pick_btn.setEnabled(False)
|
||||
try:
|
||||
token = self._cloud_token()
|
||||
|
||||
Reference in New Issue
Block a user