| 3566 | } |
| 3567 | |
| 3568 | fn resolve_tui_base_url() -> String { |
| 3569 | if let Ok(value) = std::env::var("OPENCODE_TUI_BASE_URL") { |
| 3570 | let trimmed = value.trim(); |
| 3571 | if !trimmed.is_empty() { |
| 3572 | return trimmed.to_string(); |
| 3573 | } |
| 3574 | } |
| 3575 | |
| 3576 | // Prefer a live backend endpoint over a hardcoded default. This avoids |
| 3577 | // accidental 404s when localhost:3000 is occupied by a non-opencode service. |
| 3578 | let candidates = [ |
| 3579 | "http://127.0.0.1:3000", |
| 3580 | "http://localhost:3000", |
| 3581 | "http://127.0.0.1:4096", |
| 3582 | "http://localhost:4096", |
| 3583 | ]; |
| 3584 | let client = match reqwest::blocking::Client::builder() |
| 3585 | .timeout(Duration::from_millis(300)) |
| 3586 | .build() |
| 3587 | { |
| 3588 | Ok(client) => client, |
| 3589 | Err(_) => return "http://localhost:3000".to_string(), |
| 3590 | }; |
| 3591 | |
| 3592 | for base in candidates { |
| 3593 | let health_url = format!("{}/health", base); |
| 3594 | if let Ok(response) = client.get(&health_url).send() { |
| 3595 | if response.status().is_success() { |
| 3596 | return base.to_string(); |
| 3597 | } |
| 3598 | } |
| 3599 | } |
| 3600 | |
| 3601 | "http://localhost:3000".to_string() |
| 3602 | } |
| 3603 | |
| 3604 | fn spawn_server_event_listener(event_tx: Sender<Event>, base_url: String) { |
| 3605 | thread::spawn(move || { |