feat: align browser callback runtime and export flows

Consolidate the browser task runtime around the callback path, add safer artifact opening for Zhihu exports, and cover the new service/browser flows with focused tests and supporting docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
木炎
2026-04-06 21:44:53 +08:00
parent 0dd655712c
commit bdf8e12246
55 changed files with 14440 additions and 1053 deletions

View File

@@ -106,6 +106,53 @@ fn browser_tool_exposes_privileged_surface_metadata_backed_by_mac_policy() {
);
}
#[test]
fn browser_tool_accepts_approved_local_dashboard_navigate_request() {
let transport = Arc::new(MockTransport::new(vec![BrowserMessage::Response {
seq: 1,
success: true,
data: serde_json::json!({"navigated": true}),
aom_snapshot: vec![],
timing: Timing {
queue_ms: 1,
exec_ms: 20,
},
}]));
let tool = BrowserPipeTool::new(transport.clone(), test_policy(), vec![1, 2, 3, 4])
.with_response_timeout(Duration::from_secs(1));
let result = tool
.invoke(
Action::Navigate,
serde_json::json!({
"url": "file:///C:/tmp/zhihu-hotlist-screen.html",
"sgclaw_local_dashboard_open": {
"source": "compat.workflow_executor",
"kind": "zhihu_hotlist_screen",
"output_path": "C:/tmp/zhihu-hotlist-screen.html",
"presentation_url": "file:///C:/tmp/zhihu-hotlist-screen.html"
}
}),
"__sgclaw_local_dashboard__",
)
.unwrap();
let sent = transport.sent_messages();
assert!(result.success);
assert!(matches!(
&sent[0],
AgentMessage::Command {
action,
params,
security,
..
} if action == &Action::Navigate
&& security.expected_domain == "__sgclaw_local_dashboard__"
&& params["url"] == serde_json::json!("file:///C:/tmp/zhihu-hotlist-screen.html")
&& params["sgclaw_local_dashboard_open"]["kind"] == serde_json::json!("zhihu_hotlist_screen")
));
}
#[test]
fn default_rules_allow_zhihu_navigation() {
let rules_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
@@ -115,3 +162,22 @@ fn default_rules_allow_zhihu_navigation() {
policy.validate(&Action::Navigate, "www.zhihu.com").unwrap();
}
#[test]
fn mac_policy_rejects_non_html_local_dashboard_presentation() {
let rules_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("resources")
.join("rules.json");
let policy = MacPolicy::load_from_path(rules_path).unwrap();
let err = policy
.validate_local_dashboard_presentation(
&Action::Navigate,
"__sgclaw_local_dashboard__",
"file:///C:/tmp/zhihu-hotlist-screen.txt",
"C:/tmp/zhihu-hotlist-screen.txt",
)
.unwrap_err();
assert!(err.to_string().contains("local dashboard"));
}