diff --git a/crates/workspace-server/src/server.rs b/crates/workspace-server/src/server.rs index 2aff2549..ffa467b8 100644 --- a/crates/workspace-server/src/server.rs +++ b/crates/workspace-server/src/server.rs @@ -254,6 +254,7 @@ pub struct ExtensionPoints { pub struct ExtensionPointState { pub status: String, pub note: String, + pub diagnostics: Vec, } #[derive(Debug, Serialize, Deserialize)] @@ -339,6 +340,8 @@ async fn get_workspace(State(api): State) -> ApiResult) -> ApiResult ExtensionPointState { + let completion = status.transport.completion.clone(); + let note = match completion.as_str() { + "connected" => "Workspace Companion is input-capable and browser input is dispatched through the normal Worker runtime path.".to_string(), + "not_input_capable" => { + let diagnostic_codes = status + .diagnostics + .iter() + .map(|diagnostic| diagnostic.code.as_str()) + .collect::>() + .join(", "); + if diagnostic_codes.is_empty() { + "Workspace Companion is not input-capable; check provider, config, profile, secret, and authority diagnostics.".to_string() + } else { + format!( + "Workspace Companion is not input-capable; check typed diagnostics: {diagnostic_codes}." + ) + } + } + other => format!( + "Workspace Companion transport reports {other}; browser input follows the Companion Worker runtime capability state." + ), + }; + ExtensionPointState { + status: completion, + note, + diagnostics: status.diagnostics.clone(), + } +} + async fn list_tickets( State(api): State, ) -> ApiResult>> { @@ -1132,6 +1164,24 @@ mod tests { workspace["extension_points"]["host_worker_bridge"]["status"], "runtime_registry" ); + let workspace_companion = &workspace["extension_points"]["companion_console"]; + assert_ne!(workspace_companion["status"], "not_connected"); + assert!( + !workspace_companion["note"] + .as_str() + .unwrap() + .contains("browser input remains disabled"), + "stale Companion Console note returned: {workspace_companion}" + ); + if workspace_companion["status"] == "not_input_capable" { + assert!( + !workspace_companion["diagnostics"] + .as_array() + .unwrap() + .is_empty(), + "not_input_capable workspace companion_console lacks typed diagnostics: {workspace_companion}" + ); + } let tickets = get_json(app.clone(), "/api/tickets").await; assert_eq!(tickets["items"][0]["id"], "00000000001J2"); @@ -1359,6 +1409,22 @@ mod tests { .unwrap(); let app = build_router(api); + let workspace = get_json(app.clone(), "/api/workspace").await; + let workspace_companion = &workspace["extension_points"]["companion_console"]; + assert_eq!(workspace_companion["status"], "connected"); + assert!( + workspace_companion["diagnostics"] + .as_array() + .unwrap() + .is_empty() + ); + assert!( + workspace_companion["note"] + .as_str() + .unwrap() + .contains("normal Worker runtime path") + ); + let status = get_json(app.clone(), "/api/companion/status").await; assert_eq!(status["transport"]["completion"], "connected"); let worker_id = status["worker"]["worker_id"].as_str().unwrap().to_string(); diff --git a/web/workspace/src/lib/workspace-sidebar/types.ts b/web/workspace/src/lib/workspace-sidebar/types.ts index 305e9da1..6702c710 100644 --- a/web/workspace/src/lib/workspace-sidebar/types.ts +++ b/web/workspace/src/lib/workspace-sidebar/types.ts @@ -9,6 +9,7 @@ export type { PodProtocolEvent, PodProtocolMethod, PodProtocolSegment }; export type ExtensionPoint = { status: string; note: string; + diagnostics: Diagnostic[]; }; export type WorkspaceResponse = {