feat: realign zhihu browser callback runtime

Keep Zhihu browser-attached execution on the callback-host path so direct routes, runtime wiring, and service startup stay aligned for the current websocket browser flow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
木炎
2026-04-06 12:09:47 +08:00
parent 3e18350320
commit 6068a8228b
9 changed files with 1907 additions and 116 deletions

View File

@@ -36,43 +36,62 @@ fn run() -> Result<(), String> {
.unwrap_or_else(|_| "ws://127.0.0.1:42321".to_string());
let (mut socket, _) = connect(service_url.as_str()).map_err(|err| err.to_string())?;
let mut input = String::new();
io::stdin()
.lock()
.read_line(&mut input)
.map_err(|err| err.to_string())?;
let (request, exit_on_status) = parse_request(&input);
let payload = serde_json::to_string(&request).map_err(|err| err.to_string())?;
socket
.send(Message::Text(payload.into()))
.map_err(|err| err.to_string())?;
let stdin = io::stdin();
loop {
match socket.read().map_err(|err| err.to_string())? {
Message::Text(text) => {
let message: ServiceMessage =
serde_json::from_str(&text).map_err(|err| err.to_string())?;
match message {
ServiceMessage::StatusChanged { state } => {
println!("status: {state}");
if exit_on_status {
return Ok(());
eprint!("> ");
let mut input = String::new();
let bytes_read = stdin
.lock()
.read_line(&mut input)
.map_err(|err| err.to_string())?;
if bytes_read == 0 {
break; // EOF — graceful exit
}
if input.trim().is_empty() {
continue;
}
let (request, exit_on_status) = parse_request(&input);
let payload = serde_json::to_string(&request).map_err(|err| err.to_string())?;
socket
.send(Message::Text(payload.into()))
.map_err(|err| err.to_string())?;
// Inner loop: consume service messages until the task finishes.
loop {
match socket.read().map_err(|err| err.to_string())? {
Message::Text(text) => {
let message: ServiceMessage =
serde_json::from_str(&text).map_err(|err| err.to_string())?;
match message {
ServiceMessage::StatusChanged { state } => {
println!("status: {state}");
if exit_on_status {
break;
}
}
ServiceMessage::LogEntry { level: _, message } => {
println!("{message}");
}
ServiceMessage::TaskComplete { success: _, summary } => {
println!("{summary}");
break;
}
ServiceMessage::Busy { message } => {
eprintln!("busy: {message}");
break;
}
}
ServiceMessage::LogEntry { level: _, message } => {
println!("{message}");
}
ServiceMessage::TaskComplete { success: _, summary } => {
println!("{summary}");
return Ok(());
}
ServiceMessage::Busy { message } => return Err(message),
}
Message::Close(_) => {
return Err("service disconnected".to_string());
}
_ => {}
}
Message::Close(_) => return Err("service disconnected before task completion".to_string()),
_ => {}
}
}
Ok(())
}