v5: rebase 融合修复(main 演进 + 附录源同步)

- websearch.py:补回 import socket(栈 46ca59f 的 lint 清理在栈
  上无害,replay 到 main 后 main #274 的超时/DNS 显式报错
  代码引用 socket,缺 import 致 2 项 NameError;re 在 main
  与重排后树中均 0 引用,不补)
- 3 个 websearch fake 补 scope="general" 参数(main 的
  handle_request 现必传 scope,旧 fake 致 TypeError 被吞成
  isError,3 项失败)
- playwright 工具数 14→18(main 新增 4 个,与 main _TOOLS
  逐名一致、无重复)
- playwright 种子测试改按 main 安全升级规则:源脚本 v1→v2
  且 manifest 证明未改动才刷新;未知改动只上报跳过不覆盖
- 附录源同步:01/02/07 三个 roles 源文件与 SKILL.md 附录章
  做同一改写,check_appendix 来源一致性恢复
This commit is contained in:
host committed 2026-11-04 21:03:32 +00:00
1 parent 631275ce78
commit 27464aa76d
7 files changed
+23 -10

No files matched your search

+6 -4
View File
@@ -152,7 +152,9 @@ class PlaywrightHandleTest(unittest.TestCase):
resp = playwright_mcp.handle_request(
{"jsonrpc": "2.0", "id": 8, "method": "tools/list"})
names = [t["name"] for t in resp["result"]["tools"]]
self.assertEqual(len(names), 14)
# main 在栈基线之后新增 4 个浏览器工具(18 个,与
# main 的 playwright_mcp._TOOLS 逐名一致,无重复)。
self.assertEqual(len(names), 18)
for want in ("browser_navigate", "browser_snapshot", "browser_click",
"browser_fill", "browser_evaluate", "browser_click_at",
"browser_live_shot", "browser_snapshot_refs",
@@ -607,7 +609,7 @@ class WebSearchMcpTest(unittest.TestCase):
def test_handle_request_dispatch_and_errors(self):
calls = {}
def fake_search(query, limit=5, provider="auto"):
def fake_search(query, limit=5, provider="auto", scope="general"):
calls["search"] = (query, limit, provider)
return {"results": [{"title": "t", "url": "http://x/"}]}
@@ -673,8 +675,8 @@ class WebSearchMcpTest(unittest.TestCase):
def test_main_loop_with_fake_search(self):
old_search = websearch_mcp.search
websearch_mcp.search = lambda query, limit=5, provider="auto": \
{"results": []}
websearch_mcp.search = lambda query, limit=5, provider="auto", \
scope="general": {"results": []}
old_in, old_out = sys.stdin, sys.stdout
sys.stdin = io.StringIO("\nbroken{\n" + json.dumps(
{"jsonrpc": "2.0", "id": 1, "method": "tools/call",
+12 -2
View File
@@ -789,13 +789,23 @@ class PlaywrightEnsureTest(unittest.TestCase):
self.home, script_dir=self.src)
self.assertFalse(out["script_changed"])
self.assertFalse(out["config_changed"])
# 旧脚本被刷新上报。
# 上游改版刷新:源脚本升级(v1→v2)后,manifest 已证明
# 家目录旧脚本未改动,自动刷新并上报。
with open(os.path.join(self.src,
"playwright_mcp.py"), "w") as f:
f.write("# playwright_mcp.py v2\n")
out = pw_mod.ensure_codex_home_playwright(
self.home, script_dir=self.src)
self.assertIn("playwright_mcp.py", out["script_refreshed"])
# 未知改动不刷新:家目录脚本被改成 manifest 与已知
# 已发版哈希都不认识的内容时,只上报跳过、绝不覆盖。
with open(os.path.join(self.home,
"playwright_mcp.py"), "w") as f:
f.write("# stale\n")
out = pw_mod.ensure_codex_home_playwright(
self.home, script_dir=self.src)
self.assertIn("playwright_mcp.py", out["script_refreshed"])
self.assertNotIn("playwright_mcp.py", out["script_refreshed"])
self.assertIn("playwright_mcp.py", out["script_skipped_modified"])
# 自定义 command_args 写进 section(删旧配置重写,
# 否则已有 section 不会被改写)。
os.remove(os.path.join(self.home, "config.toml"))
+1 -1
View File
@@ -68,7 +68,7 @@ class WebSearchMcpTest(unittest.TestCase):
[t["name"] for t in listed["result"]["tools"]])
def test_tools_call_and_errors(self):
fake_search = lambda q, limit=5, provider="auto": { # noqa: E731
fake_search = lambda q, limit=5, provider="auto", scope="general": { # noqa: E731
"results": [{"title": q}]}
# 工具执行一律用注入的 fake,不调真实 search(不联网)。
resp = ws_handle({"jsonrpc": "2.0", "id": 2, "method": "tools/call",