From 011f9e14bca6e47b9012f4a98ea8899f9a9689da Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Wed, 12 Aug 2026 11:23:27 +0800 Subject: [PATCH] =?UTF-8?q?fix(file-manager):=20direct=20=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E7=8E=AF=E5=A2=83=E4=B8=8B=E6=96=87=E4=BB=B6=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E4=B8=8D=E5=86=8D=E8=AF=AF=E6=8B=A6=E6=8E=88=E6=9D=83?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E5=A4=96=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit run_command 是否走沙箱只看执行环境,而 read_file/write_file/edit_file 是 进程内文件操作不走 OS 沙箱,唯一防线是 FileManager._ensure_host_access 的授权路径检查,但它不知道执行环境,导致完全访问权限(direct)下仍按 授权列表拦截。现 FileManager 同步 host_execution_mode,direct 时与 run_command 语义对齐直接放行,sandbox 模式检查保持不变。 --- core/main_terminal.py | 2 ++ modules/file_manager/base.py | 7 +++++++ modules/file_manager/path_mixin.py | 5 +++++ 3 files changed, 14 insertions(+) diff --git a/core/main_terminal.py b/core/main_terminal.py index e08bc4cb..a81a951a 100644 --- a/core/main_terminal.py +++ b/core/main_terminal.py @@ -259,6 +259,8 @@ class MainTerminal(MainTerminalCommandMixin, MainTerminalContextMixin, MainTermi self.terminal_manager.set_host_execution_mode(mode) if getattr(self, "sub_agent_manager", None): self.sub_agent_manager.set_host_execution_mode(mode) + if getattr(self, "file_manager", None): + self.file_manager.set_host_execution_mode(mode) def _init_host_network_permission(self): default_permission = str(HOST_SANDBOX_NETWORK_PERMISSION or "restricted").strip().lower() diff --git a/modules/file_manager/base.py b/modules/file_manager/base.py index 85ad3484..9d20015a 100644 --- a/modules/file_manager/base.py +++ b/modules/file_manager/base.py @@ -54,8 +54,15 @@ class FileManagerBase: self.container_session: Optional["ContainerHandle"] = None self._container_proxy: Optional[ContainerFileProxy] = None self._data_dir: Optional[str] = data_dir + # 宿主机执行环境(sandbox / direct),由主终端同步; + # direct 时与 run_command 对齐:不走路径授权检查(不套沙箱语义)。 + self.host_execution_mode: str = "sandbox" self.set_container_session(container_session) + def set_host_execution_mode(self, mode: str) -> None: + normalized = str(mode or "").strip().lower() + self.host_execution_mode = "direct" if normalized == "direct" else "sandbox" + def _load_personalization_config(self) -> Optional[Dict]: """加载个性化配置""" if not self._data_dir: diff --git a/modules/file_manager/path_mixin.py b/modules/file_manager/path_mixin.py index b45341f2..a40d3d5b 100644 --- a/modules/file_manager/path_mixin.py +++ b/modules/file_manager/path_mixin.py @@ -175,6 +175,11 @@ class PathMixin: def _ensure_host_access(self, full_path: Path, access: str) -> Tuple[bool, str]: if not self._is_host_mode(): return True, "" + # 执行环境为 direct(完全访问权限)时,run_command 不套沙箱、可读写任意路径; + # read_file/write_file/edit_file 为进程内文件操作,本就不走 OS 沙箱,此处与 + # run_command 语义对齐,直接放行。sandbox 模式下保持授权范围检查不变。 + if getattr(self, "host_execution_mode", "sandbox") == "direct": + return True, "" check_target = full_path if access == "write" and not full_path.exists(): check_target = full_path.parent.resolve()