4runr-os 2.10.49 → 2.10.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -746,7 +746,8 @@ impl App {
746
746
  ws: &WebSocketClient,
747
747
  section: MonitoringSection,
748
748
  ) {
749
- if self.state.pending_monitoring_refresh_id.is_some()
749
+ if self.state.pending_gateway_observability_id.is_some()
750
+ || self.state.pending_monitoring_refresh_id.is_some()
750
751
  || self.state.pending_monitoring_logs_id.is_some()
751
752
  || self.state.pending_monitoring_drill_id.is_some()
752
753
  {
@@ -774,7 +775,8 @@ impl App {
774
775
 
775
776
  /// Phase 2: fetch Gateway log buffer (`monitoring.logs`).
776
777
  pub fn begin_monitoring_logs_request(&mut self, ws: &WebSocketClient) {
777
- if self.state.pending_monitoring_refresh_id.is_some()
778
+ if self.state.pending_gateway_observability_id.is_some()
779
+ || self.state.pending_monitoring_refresh_id.is_some()
778
780
  || self.state.pending_monitoring_logs_id.is_some()
779
781
  || self.state.pending_monitoring_drill_id.is_some()
780
782
  {
@@ -805,7 +807,8 @@ impl App {
805
807
  ws: &WebSocketClient,
806
808
  panel: MetricsDrillPanel,
807
809
  ) {
808
- if self.state.pending_monitoring_refresh_id.is_some()
810
+ if self.state.pending_gateway_observability_id.is_some()
811
+ || self.state.pending_monitoring_refresh_id.is_some()
809
812
  || self.state.pending_monitoring_logs_id.is_some()
810
813
  || self.state.pending_monitoring_drill_id.is_some()
811
814
  {
@@ -835,7 +838,8 @@ impl App {
835
838
 
836
839
  /// Phase 3: dependency pools + queue counts (`dependencies/detail`).
837
840
  pub fn begin_dependencies_detail_drill(&mut self, ws: &WebSocketClient) {
838
- if self.state.pending_monitoring_refresh_id.is_some()
841
+ if self.state.pending_gateway_observability_id.is_some()
842
+ || self.state.pending_monitoring_refresh_id.is_some()
839
843
  || self.state.pending_monitoring_logs_id.is_some()
840
844
  || self.state.pending_monitoring_drill_id.is_some()
841
845
  {
@@ -863,7 +867,8 @@ impl App {
863
867
 
864
868
  /// Phase 4: run local CLI/host diagnostics for the System section.
865
869
  pub fn begin_system_diagnostics_request(&mut self, ws: &WebSocketClient) {
866
- if self.state.pending_monitoring_refresh_id.is_some()
870
+ if self.state.pending_gateway_observability_id.is_some()
871
+ || self.state.pending_monitoring_refresh_id.is_some()
867
872
  || self.state.pending_monitoring_logs_id.is_some()
868
873
  || self.state.pending_monitoring_drill_id.is_some()
869
874
  {
@@ -931,24 +936,15 @@ impl App {
931
936
  self.request_immediate_render("portal_obs_scroll");
932
937
  }
933
938
 
934
- /// Drop in-flight `monitoring.*` / drill work without orphaning `gateway.observability`
935
- /// (clearing that id makes the snapshot response a no-op and can stall the portal).
936
- fn cancel_portal_monitoring_aux_requests(&mut self) {
939
+ fn cancel_portal_monitoring_requests(&mut self) {
940
+ self.state.pending_gateway_observability_id = None;
937
941
  self.state.pending_monitoring_refresh_id = None;
938
942
  self.state.pending_monitoring_logs_id = None;
939
943
  self.state.pending_monitoring_drill_id = None;
944
+ self.state.portal_monitoring.loading = false;
940
945
  self.state.portal_monitoring.section_refresh_loading = None;
941
946
  self.state.portal_monitoring.logs_fetch_loading = false;
942
947
  self.state.portal_monitoring.metrics_drill_loading = false;
943
- if self.state.pending_gateway_observability_id.is_none() {
944
- self.state.portal_monitoring.loading = false;
945
- }
946
- }
947
-
948
- fn cancel_portal_monitoring_requests(&mut self) {
949
- self.cancel_portal_monitoring_aux_requests();
950
- self.state.pending_gateway_observability_id = None;
951
- self.state.portal_monitoring.loading = false;
952
948
  }
953
949
 
954
950
  /// CLI ↔ TUI WebSocket lost: drop Gateway link UI and leave Portal Monitoring / Connection Portal so the session does not appear still "connected".
@@ -2815,7 +2811,7 @@ impl App {
2815
2811
  .monitoring_state
2816
2812
  .expand_section(MonitoringSection::Logs);
2817
2813
  if let Some(ws) = ws_client {
2818
- self.cancel_portal_monitoring_aux_requests();
2814
+ self.cancel_portal_monitoring_requests();
2819
2815
  self.begin_monitoring_logs_request(ws);
2820
2816
  let inner_h = self.state.portal_monitoring.viewport_lines.max(5);
2821
2817
  let sw = self.state.portal_monitoring.summary_clip_width.max(24);
@@ -2895,7 +2891,7 @@ impl App {
2895
2891
  MonitoringSection::Dependencies,
2896
2892
  );
2897
2893
  if let Some(ws) = ws_client {
2898
- self.cancel_portal_monitoring_aux_requests();
2894
+ self.cancel_portal_monitoring_requests();
2899
2895
  self.begin_dependencies_detail_drill(ws);
2900
2896
  self.request_immediate_render("portal_deps_drill");
2901
2897
  } else {
@@ -2907,33 +2903,9 @@ impl App {
2907
2903
  }
2908
2904
 
2909
2905
  // Phase 4: diagnostics for the local CLI/TUI bridge + Gateway reachability.
2910
- // S toggles like L for logs: second press dismisses the drill (does not cancel in-flight
2911
- // gateway.observability that was orphaning snapshots and making S feel "stuck").
2906
+ // S toggles: show diagnostics hide (remove override). While loading, S aborts the
2907
+ // in-flight drill so a later S can fetch again (avoids orphaned request ids vs cancel+refetch).
2912
2908
  if key.code == KeyCode::Char('s') || key.code == KeyCode::Char('S') {
2913
- let system_lines_open = self
2914
- .state
2915
- .portal_monitoring
2916
- .section_overrides
2917
- .contains_key(&MonitoringSection::System);
2918
- let system_request_inflight = self
2919
- .state
2920
- .portal_monitoring
2921
- .section_refresh_loading
2922
- == Some(MonitoringSection::System);
2923
- if system_lines_open && !system_request_inflight {
2924
- self.state
2925
- .advanced_monitoring
2926
- .monitoring_state
2927
- .collapse_section(MonitoringSection::System);
2928
- self.state
2929
- .portal_monitoring
2930
- .section_overrides
2931
- .remove(&MonitoringSection::System);
2932
- self.state.portal_monitoring.scroll_offset = 0;
2933
- self.state.portal_monitoring.error = None;
2934
- self.request_immediate_render("portal_system_diagnostics_close");
2935
- return Ok(false);
2936
- }
2937
2909
  self.state
2938
2910
  .advanced_monitoring
2939
2911
  .monitoring_state
@@ -2950,8 +2922,26 @@ impl App {
2950
2922
  inner_h,
2951
2923
  MonitoringSection::System,
2952
2924
  );
2925
+
2926
+ let pm = &mut self.state.portal_monitoring;
2927
+ let has_system_diag =
2928
+ pm.section_overrides.contains_key(&MonitoringSection::System);
2929
+ let system_loading = pm.section_refresh_loading == Some(MonitoringSection::System);
2930
+
2931
+ if has_system_diag && !system_loading {
2932
+ pm.section_overrides.remove(&MonitoringSection::System);
2933
+ self.request_immediate_render("portal_system_dismiss");
2934
+ return Ok(false);
2935
+ }
2936
+ if system_loading {
2937
+ self.state.pending_monitoring_drill_id = None;
2938
+ self.state.portal_monitoring.section_refresh_loading = None;
2939
+ self.request_immediate_render("portal_system_abort_fetch");
2940
+ return Ok(false);
2941
+ }
2942
+
2953
2943
  if let Some(ws) = ws_client {
2954
- self.cancel_portal_monitoring_aux_requests();
2944
+ self.cancel_portal_monitoring_requests();
2955
2945
  self.begin_system_diagnostics_request(ws);
2956
2946
  self.request_immediate_render("portal_system_diagnostics");
2957
2947
  } else {
@@ -2980,7 +2970,7 @@ impl App {
2980
2970
  MonitoringSection::Metrics,
2981
2971
  );
2982
2972
  if let Some(ws) = ws_client {
2983
- self.cancel_portal_monitoring_aux_requests();
2973
+ self.cancel_portal_monitoring_requests();
2984
2974
  let panel = self
2985
2975
  .state
2986
2976
  .portal_monitoring
@@ -3056,9 +3046,29 @@ impl App {
3056
3046
  .map(|section| section.expanded)
3057
3047
  .unwrap_or(false);
3058
3048
 
3049
+ let system_selected_and_diagnostics = self
3050
+ .state
3051
+ .advanced_monitoring
3052
+ .monitoring_state
3053
+ .selected_section
3054
+ == Some(MonitoringSection::System)
3055
+ && self
3056
+ .state
3057
+ .advanced_monitoring
3058
+ .monitoring_state
3059
+ .sections
3060
+ .get(&MonitoringSection::System)
3061
+ .map(|section| section.expanded)
3062
+ .unwrap_or(false)
3063
+ && self
3064
+ .state
3065
+ .portal_monitoring
3066
+ .section_overrides
3067
+ .contains_key(&MonitoringSection::System);
3068
+
3059
3069
  match key.code {
3060
3070
  KeyCode::Up => {
3061
- if logs_selected_and_open {
3071
+ if logs_selected_and_open || system_selected_and_diagnostics {
3062
3072
  self.state.portal_monitoring.scroll_offset =
3063
3073
  self.state.portal_monitoring.scroll_offset.saturating_sub(1);
3064
3074
  self.request_immediate_render("portal_obs_scroll");
@@ -3072,7 +3082,7 @@ impl App {
3072
3082
  }
3073
3083
  }
3074
3084
  KeyCode::Down => {
3075
- if logs_selected_and_open {
3085
+ if logs_selected_and_open || system_selected_and_diagnostics {
3076
3086
  self.state.portal_monitoring.scroll_offset =
3077
3087
  (self.state.portal_monitoring.scroll_offset + 1).min(max_scroll);
3078
3088
  self.request_immediate_render("portal_obs_scroll");