diff --git a/frontend/service-console/sg_claw_service_console.html b/frontend/service-console/sg_claw_service_console.html
new file mode 100644
index 0000000..1dc2491
--- /dev/null
+++ b/frontend/service-console/sg_claw_service_console.html
@@ -0,0 +1,532 @@
+
+
+
+
+
+ sgClaw Service Console
+
+
+
+
+
+
sgClaw Service Console
+
直接连接现有 service websocket,提交自然语言任务,并持续查看 service 返回的状态、日志和完成结果。
+
+
+
+
+
+
+
+
Service Stream
+
消息流
+
只展示本地连接状态与现有 service message。
+
+
+
+
尚无消息。先连接 service websocket,再发送一条自然语言任务。
+
+
+
+
+
+
+
+
diff --git a/tests/service_console_html_test.rs b/tests/service_console_html_test.rs
new file mode 100644
index 0000000..dff93e0
--- /dev/null
+++ b/tests/service_console_html_test.rs
@@ -0,0 +1,21 @@
+use std::fs;
+use std::path::PathBuf;
+
+#[test]
+fn service_console_html_stays_on_service_ws_boundary() {
+ let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
+ let html_path = manifest_dir
+ .join("frontend")
+ .join("service-console")
+ .join("sg_claw_service_console.html");
+ let source = fs::read_to_string(&html_path).expect("service console html should exist");
+
+ assert!(source.contains("ws://127.0.0.1:42321"));
+ assert!(source.contains("submit_task"));
+ assert!(!source.contains("/sgclaw/browser-helper.html"));
+ assert!(!source.contains("/sgclaw/callback/ready"));
+ assert!(!source.contains("/sgclaw/callback/events"));
+ assert!(!source.contains("/sgclaw/callback/commands/next"));
+ assert!(!source.contains("/sgclaw/callback/commands/ack"));
+ assert!(!source.contains("ws://127.0.0.1:12345"));
+}