fix: preserve Codex tool policies when synchronizing MCP

This commit is contained in:
chenmingxuan committed 2026-10-18 20:56:06 +08:00
1 parent bdc75d0c65
commit 351b2fc905
3 files changed
+97 -12

No files matched your search

+72
View File
@@ -136,6 +136,78 @@ command = "leave-alone"
assert path.with_name(path.name + ".artemis-update.bak").read_text(encoding="utf-8") == original
@pytest.mark.parametrize(
"policies",
[
'# Keep my tool policies\ntools = { mobile_run_task = { enabled = false, approval_policy = "on-request" }, retired_tool = { enabled = false } }\n',
'# Keep my tool policies\ntools.mobile_run_task.enabled = false\ntools.mobile_run_task.approval_policy = "on-request"\ntools.retired_tool.enabled = false\n',
'# Keep my tool policies\n[mcp_servers.artemis.tools.mobile_run_task]\nenabled = false\napproval_policy = "on-request"\n[mcp_servers.artemis.tools.retired_tool]\nenabled = false\n',
],
ids=["inline-table", "dotted-keys", "tool-subtables"],
)
def test_codex_sync_preserves_tool_policies_verbatim(tmp_path, monkeypatch, policies):
from artemis.interfaces.cli.commands import mcp as mcp_command
codex_home = tmp_path / "中文用户" / ".codex"
codex_home.mkdir(parents=True)
path = codex_home / "config.toml"
original = (
'[mcp_servers.artemis]\ncommand = "old-python"\n'
'args = ["-m", "mcp_server"]\n'
'enabled_tools = ["mobile_run_task"]\n'
'disabled_tools = ["mobile_config"]\n'
'env = { PYTHONPATH = "C:/old", OPENAI_API_KEY = "test-secret" }\n'
+ policies
+ '[mcp_servers.other]\ncommand = "leave-alone"\n'
)
path.write_text(original, encoding="utf-8")
before = tomllib.loads(original)
monkeypatch.setenv("CODEX_HOME", str(codex_home))
root = tmp_path / "新版项目"
assert update.refresh_mcp(root) == 0
refreshed = path.read_text(encoding="utf-8")
after = tomllib.loads(refreshed)
entry = after["mcp_servers"]["artemis"]
assert entry["command"] == update.sys.executable
assert entry["cwd"] == str(root)
assert entry["env"] == {
"PYTHONPATH": str(root),
"OPENAI_API_KEY": "test-secret",
"PYTHONUNBUFFERED": "1",
"ARTEMIS_DESKTOP_NOTIFY": "true",
}
assert entry["enabled_tools"] == list(mcp_command.ARTEMIS_MCP_TOOLS)
assert entry["disabled_tools"] == ["mobile_config"]
assert entry["tools"] == before["mcp_servers"]["artemis"]["tools"]
assert policies.split("\n", 1)[1] in refreshed
assert refreshed.count("# Keep my tool policies") == 1
assert after["mcp_servers"]["other"] == before["mcp_servers"]["other"]
assert path.with_name(path.name + ".artemis-update.bak").read_text(encoding="utf-8") == original
assert update.refresh_mcp(root) == 0
assert path.read_text(encoding="utf-8") == refreshed
def test_codex_sync_reports_generated_toml_error_without_blame_or_overwrite(
tmp_path, monkeypatch, capsys
):
codex_home = tmp_path / ".codex"
codex_home.mkdir()
path = codex_home / "config.toml"
original = '[mcp_servers.artemis]\ncommand = "old"\nargs = ["-m", "mcp_server"]\n'
path.write_text(original, encoding="utf-8")
monkeypatch.setenv("CODEX_HOME", str(codex_home))
monkeypatch.setenv("ARTEMIS_LAUNCH_LANG", "zh-CN")
monkeypatch.setattr(update, "_replace_toml_tables", lambda *_: 'tools = {"secret": true}\n')
assert update.refresh_mcp(tmp_path / "project") == 1
assert path.read_text(encoding="utf-8") == original
assert not path.with_name(path.name + ".artemis-update.bak").exists()
output = capsys.readouterr().out
assert "原配置可正常解析" in output
assert "ARTEMIS 同步错误" in output
assert "配置结构无效" not in output
assert "secret" not in output
def test_mcp_sync_updates_only_codex_and_preserves_other_clients(tmp_path, monkeypatch):
from artemis.interfaces.cli.commands import mcp as mcp_command