统一公共工具并移除 workspace 专家链路。

将文件/命令/Git/检索能力统一迁入 public,去除重复工具与 local_ 命名前缀,并重命名底层路径守卫模块为 path_guard 以提升语义清晰度。

Made-with: Cursor
This commit is contained in:
oliver 2026-05-01 00:38:31 +08:00
parent 75aec2abe4
commit d0a66d190d
21 changed files with 326 additions and 1012 deletions

View file

@ -12,9 +12,9 @@ from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.experts.workspace.fs_tools import list_files_tool, write_file_tool
from oclaw.runtime.tools.experts.workspace.shell_tools import run_command_tool
from oclaw.runtime.tools.experts.workspace.workspace_base import (
from oclaw.runtime.tools.public.glob_tool import glob_tool
from oclaw.runtime.tools.public.write_file_tool import write_file_tool
from oclaw.runtime.tools.path_guard import (
access_from_env,
build_workspace_path_access,
clear_workspace_path_access_for_tests,
@ -79,7 +79,7 @@ class WorkspacePathGuardTests(unittest.TestCase):
clear=False,
):
clear_workspace_path_access_for_tests()
spec = list_files_tool()
spec = glob_tool()
with workspace_path_access_scope(None, None):
r = spec.handler({"root": str(sub), "pattern": "**/*", "max_results": 50})
self.assertTrue(r.get("ok"), r)
@ -150,224 +150,6 @@ class WorkspacePathGuardTests(unittest.TestCase):
self.assertEqual(str(expected), str(r.get("path")))
self.assertTrue(expected.exists())
def test_run_command_default_cwd_uses_workspace_namespace_sandbox(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
spec = run_command_tool()
with workspace_path_access_scope(None, None), workspace_write_namespace_scope("ops"):
r = spec.handler({"command": "python -c \"print('ok')\""})
self.assertTrue(r.get("ok"), r)
expected_cwd = (self.root / "data" / "workspace").resolve()
self.assertEqual(str(expected_cwd), str(r.get("cwd")))
def test_run_command_strips_leading_cd_chain_in_default_sandbox(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
spec = run_command_tool()
cmd = f'cd /d "{self.root}" && python -c "print(123)"'
with workspace_path_access_scope(None, None), workspace_write_namespace_scope("ops"):
r = spec.handler({"command": cmd})
self.assertTrue(r.get("ok"), r)
self.assertTrue(bool(r.get("normalized_cd_removed")))
expected_cwd = (self.root / "data" / "workspace").resolve()
self.assertEqual(str(expected_cwd), str(r.get("cwd")))
self.assertIn("123", str(r.get("output") or ""))
def test_run_command_strips_windows_drive_prefix_cd_chain(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
ws_root = self.root / "data" / "workspace"
ws_root.mkdir(parents=True, exist_ok=True)
(ws_root / "count_directory.py").write_text("print('drive-cd-ok')\n", encoding="utf-8")
spec = run_command_tool()
cmd = f'D: && cd /d "{self.root}" && python count_directory.py'
with workspace_path_access_scope(None, None):
r = spec.handler({"command": cmd})
self.assertTrue(r.get("ok"), r)
self.assertTrue(bool(r.get("normalized_cd_removed")), r)
self.assertTrue(bool(r.get("script_path_rewritten")), r)
self.assertIn("drive-cd-ok", str(r.get("output") or ""))
def test_run_command_output_flags_distinguish_empty_from_truncation(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
spec = run_command_tool()
with workspace_path_access_scope(None, None), workspace_write_namespace_scope("ops"):
r = spec.handler({"command": 'python -c "pass"'})
self.assertTrue(r.get("ok"), r)
self.assertTrue(bool(r.get("output_empty")))
self.assertFalse(bool(r.get("output_truncated")))
self.assertTrue(bool(r.get("output_not_truncated")))
self.assertEqual(str(r.get("error_code") or ""), "")
def test_run_command_nonzero_exit_marks_failure_not_truncation(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
spec = run_command_tool()
with workspace_path_access_scope(None, None), workspace_write_namespace_scope("ops"):
r = spec.handler({"command": 'python -c "import sys; sys.exit(3)"'})
self.assertFalse(bool(r.get("ok")))
self.assertEqual(int(r.get("exit_code") or 0), 3)
self.assertEqual(str(r.get("error_code") or ""), "command_exit_nonzero")
self.assertFalse(bool(r.get("output_truncated")))
def test_run_command_blocks_cocoloop_install_cli(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
spec = run_command_tool()
with workspace_path_access_scope(None, None):
r = spec.handler({"command": "cocoloop install 7288"})
self.assertFalse(bool(r.get("ok")), r)
self.assertEqual("skill_install_cli_blocked", str(r.get("error_code") or ""))
self.assertIn("market/install", str(r.get("hint") or ""))
def test_run_command_blocks_npx_clawhub_install_pattern(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
spec = run_command_tool()
with workspace_path_access_scope(None, None):
r = spec.handler({"command": "npx -y clawhub@latest install foo"})
self.assertFalse(bool(r.get("ok")), r)
self.assertEqual("skill_install_cli_blocked", str(r.get("error_code") or ""))
def test_run_command_rewrites_workspace_absolute_script_path_to_sandbox(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
# Prepare script inside sandbox, but command will reference repo-root absolute path.
ws_script = self.root / "data" / "workspace" / "count_files.py"
ws_script.parent.mkdir(parents=True, exist_ok=True)
ws_script.write_text("print('sandbox-ok')\n", encoding="utf-8")
spec = run_command_tool()
absolute_repo_script = str((self.root / "count_files.py").resolve())
with workspace_path_access_scope(None, None), workspace_write_namespace_scope("ops"):
r = spec.handler({"command": f'python "{absolute_repo_script}"'})
self.assertTrue(r.get("ok"), r)
self.assertTrue(bool(r.get("command_rewritten")), r)
self.assertIn("sandbox-ok", str(r.get("output") or ""))
def test_run_command_explicit_repo_root_cwd_is_redirected_to_sandbox(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
ws_script = self.root / "data" / "workspace" / "count_files.py"
ws_script.parent.mkdir(parents=True, exist_ok=True)
ws_script.write_text("print('redirect-ok')\n", encoding="utf-8")
spec = run_command_tool()
abs_repo_script = str((self.root / "count_files.py").resolve())
with workspace_path_access_scope(None, None):
r = spec.handler(
{
"command": f'python "{abs_repo_script}"',
"cwd": str(self.root),
}
)
self.assertTrue(r.get("ok"), r)
self.assertTrue(bool(r.get("cwd_redirected_to_sandbox")), r)
self.assertTrue(bool(r.get("command_rewritten")), r)
self.assertIn("redirect-ok", str(r.get("output") or ""))
def test_run_command_rewrites_relative_python_script_to_sandbox_root(self) -> None:
with mock.patch.dict(
os.environ,
{
"OPS_WORKSPACE_ROOT": str(self.root),
"OPS_WORKSPACE_EXTRA_ROOTS": "",
"OPS_WORKSPACE_ALLOW_ANY_PATH": "",
"AIA_ENABLE_RUN_COMMAND": "1",
},
clear=False,
):
clear_workspace_path_access_for_tests()
ws_root = self.root / "data" / "workspace"
ws_root.mkdir(parents=True, exist_ok=True)
(ws_root / "count_directory.py").write_text("print('found-in-sandbox-root')\n", encoding="utf-8")
spec = run_command_tool()
with workspace_path_access_scope(None, None):
r = spec.handler({"command": "python count_directory.py"})
self.assertTrue(r.get("ok"), r)
self.assertTrue(bool(r.get("script_path_rewritten")), r)
self.assertIn("found-in-sandbox-root", str(r.get("output") or ""))
def test_per_user_extra_roots_from_db(self) -> None:
f = self.extra / "u.txt"
f.write_text("u", encoding="utf-8")