@64mb/freelens-power 1.1.0 → 1.2.0

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.
Files changed (208) hide show
  1. package/README.md +5 -4
  2. package/THIRD_PARTY_LICENSES +1707 -0
  3. package/out/main/ai.js +63 -23
  4. package/out/main/ai.js.map +1 -1
  5. package/out/main/cluster-icons-catalog.js +28 -0
  6. package/out/main/cluster-icons-catalog.js.map +1 -0
  7. package/out/main/cluster-icons.js +125 -0
  8. package/out/main/cluster-icons.js.map +1 -0
  9. package/out/main/common/ai-terminal-context.js +51 -0
  10. package/out/main/common/ai-terminal-context.js.map +1 -0
  11. package/out/main/common/ai.js.map +1 -1
  12. package/out/main/common/cluster-icon-ipc.js +6 -0
  13. package/out/main/common/cluster-icon-ipc.js.map +1 -0
  14. package/out/main/common/cluster-icons.js +121 -0
  15. package/out/main/common/cluster-icons.js.map +1 -0
  16. package/out/main/common/dashboard.js +1 -1
  17. package/out/main/common/dashboard.js.map +1 -1
  18. package/out/main/common/settings-export.js +3 -1
  19. package/out/main/common/settings-export.js.map +1 -1
  20. package/out/main/common/store/cluster-icons-store.js +32 -0
  21. package/out/main/common/store/cluster-icons-store.js.map +1 -0
  22. package/out/main/common/store/monitoring-preferences-store.js +5 -0
  23. package/out/main/common/store/monitoring-preferences-store.js.map +1 -1
  24. package/out/main/diagnostics-menu-order.js +57 -0
  25. package/out/main/diagnostics-menu-order.js.map +1 -0
  26. package/out/main/index.js +9 -1
  27. package/out/main/index.js.map +1 -1
  28. package/out/main/monitoring-history.js +13 -3
  29. package/out/main/monitoring-history.js.map +1 -1
  30. package/out/renderer/_virtual/_global-external_react-dom.js +2 -1
  31. package/out/renderer/_virtual/_global-external_react.js +10 -5
  32. package/out/renderer/_virtual/_rolldown/runtime.js +22 -0
  33. package/out/renderer/ai-terminal-context.js +200 -0
  34. package/out/renderer/ai-terminal-context.js.map +1 -0
  35. package/out/renderer/ai.js +90 -9
  36. package/out/renderer/ai.js.map +1 -1
  37. package/out/renderer/appearance.js +1 -0
  38. package/out/renderer/appearance.js.map +1 -1
  39. package/out/renderer/cluster-icon-colors.js +188 -0
  40. package/out/renderer/cluster-icon-colors.js.map +1 -0
  41. package/out/renderer/cluster-icons.js +304 -0
  42. package/out/renderer/cluster-icons.js.map +1 -0
  43. package/out/renderer/dashboard.js +8 -5
  44. package/out/renderer/dashboard.js.map +1 -1
  45. package/out/renderer/details/secret-certificate-details.js +9 -2
  46. package/out/renderer/details/secret-certificate-details.js.map +1 -1
  47. package/out/renderer/diagnostics.css.js +39 -0
  48. package/out/renderer/diagnostics.css.js.map +1 -0
  49. package/out/renderer/diagnostics.js +796 -343
  50. package/out/renderer/diagnostics.js.map +1 -1
  51. package/out/renderer/index.js +9 -4
  52. package/out/renderer/index.js.map +1 -1
  53. package/out/renderer/monitoring-details-chart.js +42 -0
  54. package/out/renderer/monitoring-details-chart.js.map +1 -0
  55. package/out/renderer/monitoring-history-collection.js +2 -18
  56. package/out/renderer/monitoring-history-collection.js.map +1 -1
  57. package/out/renderer/monitoring-history-view.js +111 -34
  58. package/out/renderer/monitoring-history-view.js.map +1 -1
  59. package/out/renderer/monitoring.js +68 -27
  60. package/out/renderer/monitoring.js.map +1 -1
  61. package/out/renderer/node-monitoring.js +23 -12
  62. package/out/renderer/node-monitoring.js.map +1 -1
  63. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js +10 -0
  64. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js.map +1 -0
  65. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js +8 -0
  66. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js.map +1 -0
  67. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js +9 -0
  68. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js.map +1 -0
  69. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js +9 -0
  70. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js.map +1 -0
  71. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/classCallCheck.js +8 -0
  72. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/classCallCheck.js.map +1 -0
  73. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createClass.js +15 -0
  74. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createClass.js.map +1 -0
  75. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createSuper.js +19 -0
  76. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createSuper.js.map +1 -0
  77. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/defineProperty.js +14 -0
  78. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/defineProperty.js.map +1 -0
  79. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js +19 -0
  80. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js.map +1 -0
  81. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js +15 -0
  82. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js.map +1 -0
  83. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inherits.js +14 -0
  84. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inherits.js.map +1 -0
  85. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js +18 -0
  86. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js.map +1 -0
  87. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArray.js +8 -0
  88. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArray.js.map +1 -0
  89. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js +26 -0
  90. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js.map +1 -0
  91. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js +8 -0
  92. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js.map +1 -0
  93. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js +8 -0
  94. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js.map +1 -0
  95. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectSpread2.js +27 -0
  96. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectSpread2.js.map +1 -0
  97. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js +15 -0
  98. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js.map +1 -0
  99. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +14 -0
  100. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js.map +1 -0
  101. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js +12 -0
  102. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js.map +1 -0
  103. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js +15 -0
  104. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js.map +1 -0
  105. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/slicedToArray.js +12 -0
  106. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/slicedToArray.js.map +1 -0
  107. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js +8 -0
  108. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js.map +1 -0
  109. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js +12 -0
  110. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js.map +1 -0
  111. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPrimitive.js +16 -0
  112. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPrimitive.js.map +1 -0
  113. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js +11 -0
  114. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js.map +1 -0
  115. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/typeof.js +18 -0
  116. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/typeof.js.map +1 -0
  117. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js +13 -0
  118. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js.map +1 -0
  119. package/out/renderer/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js +237 -0
  120. package/out/renderer/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js.map +1 -0
  121. package/out/renderer/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js +25 -0
  122. package/out/renderer/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js.map +1 -0
  123. package/out/renderer/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js +12 -0
  124. package/out/renderer/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js.map +1 -0
  125. package/out/renderer/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@17.0.93_react@17.0.2/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js +58 -0
  126. package/out/renderer/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@17.0.93_react@17.0.2/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js.map +1 -0
  127. package/out/renderer/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@17.0.93_react@17.0.2/node_modules/@emotion/react/dist/emotion-react.browser.esm.js +54 -0
  128. package/out/renderer/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@17.0.93_react@17.0.2/node_modules/@emotion/react/dist/emotion-react.browser.esm.js.map +1 -0
  129. package/out/renderer/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js +133 -0
  130. package/out/renderer/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js.map +1 -0
  131. package/out/renderer/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js +65 -0
  132. package/out/renderer/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js.map +1 -0
  133. package/out/renderer/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js +54 -0
  134. package/out/renderer/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js.map +1 -0
  135. package/out/renderer/node_modules/.pnpm/@emotion_use-insertion-effect-with-fallbacks@1.2.0_react@17.0.2/node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js +12 -0
  136. package/out/renderer/node_modules/.pnpm/@emotion_use-insertion-effect-with-fallbacks@1.2.0_react@17.0.2/node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js.map +1 -0
  137. package/out/renderer/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js +30 -0
  138. package/out/renderer/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js.map +1 -0
  139. package/out/renderer/node_modules/.pnpm/@floating-ui_dom@1.7.2/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +211 -0
  140. package/out/renderer/node_modules/.pnpm/@floating-ui_dom@1.7.2/node_modules/@floating-ui/dom/dist/floating-ui.dom.js.map +1 -0
  141. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js +97 -0
  142. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +1 -0
  143. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +31 -0
  144. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.js.map +1 -0
  145. package/out/renderer/node_modules/.pnpm/hoist-non-react-statics@3.3.2/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js +93 -0
  146. package/out/renderer/node_modules/.pnpm/hoist-non-react-statics@3.3.2/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js.map +1 -0
  147. package/out/renderer/node_modules/.pnpm/memoize-one@6.0.0/node_modules/memoize-one/dist/memoize-one.esm.js +38 -0
  148. package/out/renderer/node_modules/.pnpm/memoize-one@6.0.0/node_modules/memoize-one/dist/memoize-one.esm.js.map +1 -0
  149. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js +159 -0
  150. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js.map +1 -0
  151. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js +103 -0
  152. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
  153. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js +18 -0
  154. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js.map +1 -0
  155. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/Select-ef7c0426.esm.js +2200 -0
  156. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/Select-ef7c0426.esm.js.map +1 -0
  157. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/index-641ee5b8.esm.js +992 -0
  158. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/index-641ee5b8.esm.js.map +1 -0
  159. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/react-select.esm.js +14 -0
  160. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/react-select.esm.js.map +1 -0
  161. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/useStateManager-7e1e8489.esm.js +56 -0
  162. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/useStateManager-7e1e8489.esm.js.map +1 -0
  163. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js +22 -0
  164. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js.map +1 -0
  165. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js +30 -0
  166. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js.map +1 -0
  167. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js +164 -0
  168. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js.map +1 -0
  169. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js +37 -0
  170. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js.map +1 -0
  171. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js +245 -0
  172. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js.map +1 -0
  173. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js +120 -0
  174. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js.map +1 -0
  175. package/out/renderer/node_modules/.pnpm/use-isomorphic-layout-effect@1.2.1_@types_react@17.0.93_react@17.0.2/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.js +6 -0
  176. package/out/renderer/node_modules/.pnpm/use-isomorphic-layout-effect@1.2.1_@types_react@17.0.93_react@17.0.2/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.js.map +1 -0
  177. package/out/renderer/pod-monitoring.js +15 -19
  178. package/out/renderer/pod-monitoring.js.map +1 -1
  179. package/out/renderer/preferences/ai-shortcuts-preferences.js +12 -4
  180. package/out/renderer/preferences/ai-shortcuts-preferences.js.map +1 -1
  181. package/out/renderer/preferences/dashboard-preferences.js +20 -4
  182. package/out/renderer/preferences/dashboard-preferences.js.map +1 -1
  183. package/out/renderer/preferences/monitoring-preferences.js +131 -44
  184. package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
  185. package/out/renderer/preferences/preferences.js +31 -7
  186. package/out/renderer/preferences/preferences.js.map +1 -1
  187. package/out/renderer/read-only.js +2 -2
  188. package/out/renderer/read-only.js.map +1 -1
  189. package/out/renderer/src/common/ai-terminal-context.js +51 -0
  190. package/out/renderer/src/common/ai-terminal-context.js.map +1 -0
  191. package/out/renderer/src/common/ai.js.map +1 -1
  192. package/out/renderer/src/common/cluster-icon-ipc.js +6 -0
  193. package/out/renderer/src/common/cluster-icon-ipc.js.map +1 -0
  194. package/out/renderer/src/common/cluster-icons.js +133 -0
  195. package/out/renderer/src/common/cluster-icons.js.map +1 -0
  196. package/out/renderer/src/common/dashboard.js +1 -1
  197. package/out/renderer/src/common/dashboard.js.map +1 -1
  198. package/out/renderer/src/common/date-time.js +11 -0
  199. package/out/renderer/src/common/date-time.js.map +1 -0
  200. package/out/renderer/src/common/monitoring-history.js +2 -0
  201. package/out/renderer/src/common/monitoring-history.js.map +1 -1
  202. package/out/renderer/src/common/resource-diagnostics.js.map +1 -1
  203. package/out/renderer/src/common/settings-export.js.map +1 -1
  204. package/out/renderer/src/common/store/monitoring-preferences-store.js +5 -0
  205. package/out/renderer/src/common/store/monitoring-preferences-store.js.map +1 -1
  206. package/out/renderer/welcome.js +28 -6
  207. package/out/renderer/welcome.js.map +1 -1
  208. package/package.json +3 -2
@@ -1,15 +1,131 @@
1
1
  const require_extensions = require("./_virtual/_global-external_@freelensapp/extensions.js");
2
2
  const require__global_external_mobx = require("./_virtual/_global-external_mobx.js");
3
- const require_monitoring_preferences_store = require("./src/common/store/monitoring-preferences-store.js");
4
3
  const require__global_external_react = require("./_virtual/_global-external_react.js");
5
4
  const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
6
5
  const require_ai_icon = require("./ai-icon.js");
6
+ const require_date_time = require("./src/common/date-time.js");
7
7
  const require_resource_diagnostics = require("./src/common/resource-diagnostics.js");
8
+ const require_diagnostics_css = require("./diagnostics.css.js");
8
9
  const require_monitoring_collector = require("./monitoring-collector.js");
9
- const require_monitoring_history_view = require("./monitoring-history-view.js");
10
- const require_monitoring = require("./monitoring.js");
11
- const require_monitoring_history_collection = require("./monitoring-history-collection.js");
12
10
  //#region src/renderer/diagnostics.tsx
11
+ var viewDescriptions = {
12
+ Consumers: ["What is using cluster resources?", "Compare workload usage and requests, then expand a workload to inspect its pods."],
13
+ Timeline: ["What changed in this workload?", "Follow related Kubernetes events and changes observed while this view is open."],
14
+ Pending: ["Why is this pod waiting?", "Inspect scheduling evidence and resource requests before opening the pod for investigation."]
15
+ };
16
+ function DiagnosticsSelect({ label, value, onChange, options }) {
17
+ return /* @__PURE__ */ require_jsx_runtime.jsx("span", {
18
+ className: "diagnostics-select",
19
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Select, {
20
+ "aria-label": label,
21
+ value,
22
+ options,
23
+ onChange: (option) => {
24
+ if (option) onChange(option.value);
25
+ },
26
+ isClearable: false
27
+ })
28
+ });
29
+ }
30
+ function ResourceCell({ summary, metric }) {
31
+ const complete = summary.coveredPods === summary.totalPods && !summary.unknownRequestPods;
32
+ const ratio = complete && summary.usage !== void 0 && summary.requests > 0 ? `${(summary.usage / summary.requests * 100).toFixed(0)}% of requests` : void 0;
33
+ return /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
34
+ className: "resource-cell",
35
+ children: [
36
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
37
+ className: "resource-value",
38
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("small", { children: "Usage" }), /* @__PURE__ */ require_jsx_runtime.jsx("strong", { children: resourceText(summary.usage, metric) })]
39
+ }),
40
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
41
+ className: "resource-request",
42
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("small", { children: summary.unknownRequestPods ? "Known requests" : "Requests" }), /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: resourceText(summary.requests, metric) })]
43
+ }),
44
+ /* @__PURE__ */ require_jsx_runtime.jsxs("small", {
45
+ className: "resource-coverage",
46
+ title: "Coverage is per resource. Missing metrics are unavailable, never zero.",
47
+ children: [
48
+ summary.coveredPods,
49
+ "/",
50
+ summary.totalPods,
51
+ " pods covered",
52
+ summary.unknownRequestPods ? ` · ${summary.unknownRequestPods} requests unknown` : "",
53
+ ratio ? ` · ${ratio}` : ""
54
+ ]
55
+ }),
56
+ complete && summary.usage !== void 0 && summary.requests > 0 && summary.usage > summary.requests && /* @__PURE__ */ require_jsx_runtime.jsxs("span", {
57
+ className: "request-burst",
58
+ title: "Usage exceeds configured requests. Requests are reservations, not limits; this alone does not indicate a failure.",
59
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
60
+ material: "info_outline",
61
+ size: 12
62
+ }), "Above requests"]
63
+ })
64
+ ]
65
+ });
66
+ }
67
+ function UnscheduledCell({ cpu, memory }) {
68
+ if (!(cpu.unknownRequestPods || memory.unknownRequestPods) && !cpu.unscheduledRequests && !memory.unscheduledRequests) return /* @__PURE__ */ require_jsx_runtime.jsx("span", {
69
+ className: "unscheduled-empty",
70
+ title: "No unscheduled requests",
71
+ children: "—"
72
+ });
73
+ return /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
74
+ className: `unscheduled-cell${cpu.unscheduledRequests || memory.unscheduledRequests ? " has-requests" : ""}`,
75
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("small", { children: "CPU" }), /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: unscheduledText(cpu, "cpu") })] }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("small", { children: "Memory" }), /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: unscheduledText(memory, "memory") })] })]
76
+ });
77
+ }
78
+ function consumerStatus(pods) {
79
+ const failureReasons = /* @__PURE__ */ new Set([
80
+ "CrashLoopBackOff",
81
+ "ImagePullBackOff",
82
+ "ErrImagePull",
83
+ "CreateContainerConfigError",
84
+ "CreateContainerError",
85
+ "RunContainerError",
86
+ "InvalidImageName"
87
+ ]);
88
+ for (const pod of pods) {
89
+ const status = pod.status;
90
+ const reason = [...status?.containerStatuses ?? [], ...status?.initContainerStatuses ?? []].map((status) => status.state?.waiting?.reason).find((value) => value && failureReasons.has(value));
91
+ if (pod.status?.phase === "Failed" || reason) return {
92
+ tone: "error",
93
+ label: reason ?? "Failed",
94
+ icon: "error_outline"
95
+ };
96
+ }
97
+ const pendingCount = pods.filter((pod) => pod.status?.phase === "Pending").length;
98
+ if (pendingCount) return {
99
+ tone: "warning",
100
+ label: `${pendingCount} Pending`,
101
+ icon: "hourglass_empty"
102
+ };
103
+ if (pods.some((pod) => pod.status?.conditions?.some((condition) => condition.type === "Ready" && condition.status === "False"))) return {
104
+ tone: "warning",
105
+ label: "Not ready",
106
+ icon: "warning_amber"
107
+ };
108
+ if (pods.length && pods.every((pod) => pod.status?.phase === "Running" && pod.status.conditions?.some((condition) => condition.type === "Ready" && condition.status === "True"))) return {
109
+ tone: "healthy",
110
+ label: "Ready",
111
+ icon: "check_circle_outline"
112
+ };
113
+ return {
114
+ tone: "neutral",
115
+ label: "Readiness unknown",
116
+ icon: "help_outline"
117
+ };
118
+ }
119
+ function ConsumerStatus({ pods }) {
120
+ const status = consumerStatus(pods);
121
+ return /* @__PURE__ */ require_jsx_runtime.jsxs("span", {
122
+ className: `consumer-status ${status.tone}`,
123
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
124
+ material: status.icon,
125
+ size: 13
126
+ }), status.label]
127
+ });
128
+ }
13
129
  var hidden = () => document.visibilityState === "hidden";
14
130
  var activeId = () => require_extensions.Renderer.Catalog.activeCluster.get()?.metadata.uid;
15
131
  var groupKey = (group) => `${group.namespace}/${group.identity}`;
@@ -17,11 +133,6 @@ function resourceText(value, metric) {
17
133
  if (value === void 0) return "Unavailable";
18
134
  return metric === "cpu" ? `${value.toFixed(3)} cores` : `${(value / 1024 ** 2).toFixed(1)} MiB`;
19
135
  }
20
- function summaryText(summary, metric) {
21
- const request = summary.unknownRequestPods ? `partial ${resourceText(summary.requests, metric)} known (${summary.unknownRequestPods} pods unknown)` : resourceText(summary.requests, metric);
22
- const ratio = summary.usage !== void 0 && summary.requests > 0 && !summary.unknownRequestPods && summary.coveredPods === summary.totalPods ? `${(summary.usage / summary.requests * 100).toFixed(0)}% of requests` : "ratio unavailable";
23
- return `${resourceText(summary.usage, metric)} (${summary.coveredPods}/${summary.totalPods} pods covered), requests ${request}, ${ratio}`;
24
- }
25
136
  function unscheduledText(summary, metric) {
26
137
  return `${summary.unknownRequestPods ? "Partial known: " : ""}${resourceText(summary.unscheduledRequests, metric)}`;
27
138
  }
@@ -43,7 +154,8 @@ var plurals = {
43
154
  Job: "jobs",
44
155
  CronJob: "cronjobs"
45
156
  };
46
- function openResource(object, clusterId) {
157
+ function openResource(object, clusterId, event) {
158
+ event.stopPropagation();
47
159
  const kind = object.kind ?? "Pod";
48
160
  if (activeId() !== clusterId || !object.metadata.name || !object.metadata.namespace || !resources[kind]) return;
49
161
  const path = `${resources[kind]}/namespaces/${encodeURIComponent(object.metadata.namespace)}/${plurals[kind]}/${encodeURIComponent(object.metadata.name)}`;
@@ -101,7 +213,7 @@ function DiagnosticsPage() {
101
213
  const [snapshot, setSnapshot] = require__global_external_react.useState();
102
214
  const [error, setError] = require__global_external_react.useState("");
103
215
  const [filter, setFilter] = require__global_external_react.useState("");
104
- const [historyTarget, setHistoryTarget] = require__global_external_react.useState("");
216
+ const [needsAttention, setNeedsAttention] = require__global_external_react.useState(true);
105
217
  const [groupMode, setGroupMode] = require__global_external_react.useState("workload");
106
218
  const [namespacesOpen, setNamespacesOpen] = require__global_external_react.useState([]);
107
219
  const known = require__global_external_react.useRef(/* @__PURE__ */ new Map());
@@ -110,7 +222,7 @@ function DiagnosticsPage() {
110
222
  const [selected, setSelected] = require__global_external_react.useState("");
111
223
  const [pendingUid, setPendingUid] = require__global_external_react.useState("");
112
224
  const [reason, setReason] = require__global_external_react.useState("");
113
- const [warningOnly, setWarningOnly] = require__global_external_react.useState(false);
225
+ const [warningOnly, setWarningOnly] = require__global_external_react.useState(true);
114
226
  const [observed, setObserved] = require__global_external_react.useState([]);
115
227
  const previous = require__global_external_react.useRef();
116
228
  require__global_external_react.useEffect(() => {
@@ -191,29 +303,48 @@ function DiagnosticsPage() {
191
303
  const data = snapshot?.clusterId === activeId() ? snapshot : void 0;
192
304
  const projected = require__global_external_react.useMemo(() => data ? projection(data) : void 0, [data]);
193
305
  const groups = projected?.groups ?? [];
194
- const filtered = require__global_external_react.useMemo(() => groups.filter((group) => `${group.namespace} ${group.name} ${group.kind}`.toLowerCase().includes(filter.toLowerCase())).sort((a, b) => sort === "name" ? groupKey(a).localeCompare(groupKey(b)) : sort === "requests" || sort === "memoryRequests" ? b[sort === "requests" ? "cpu" : "memory"].requests - a[sort === "requests" ? "cpu" : "memory"].requests : (b[sort === "memory" ? "memory" : "cpu"].usage ?? -1) - (a[sort === "memory" ? "memory" : "cpu"].usage ?? -1)), [
306
+ const filtered = require__global_external_react.useMemo(() => groups.filter((group) => `${group.namespace} ${group.name} ${group.kind}`.toLowerCase().includes(filter.toLowerCase())).filter((group) => !needsAttention || ["error", "warning"].includes(consumerStatus(group.pods).tone)).sort((a, b) => sort === "name" ? a.namespace.localeCompare(b.namespace) || a.name.localeCompare(b.name) || a.kind.localeCompare(b.kind) || a.identity.localeCompare(b.identity) : sort === "requests" || sort === "memoryRequests" ? b[sort === "requests" ? "cpu" : "memory"].requests - a[sort === "requests" ? "cpu" : "memory"].requests : (b[sort === "memory" ? "memory" : "cpu"].usage ?? -1) - (a[sort === "memory" ? "memory" : "cpu"].usage ?? -1)), [
195
307
  groups,
196
308
  filter,
197
- sort
309
+ sort,
310
+ needsAttention
198
311
  ]);
199
- const applications = [...known.current.values()].map((item) => item.group);
312
+ const warningUids = new Set((data?.events ?? []).filter((event) => event.type === "Warning").map((event) => event.involvedObject?.uid ?? event.regarding?.uid).filter((uid) => !!uid));
313
+ const applications = [...known.current.values()].filter((item) => !warningOnly || [...item.uids].some((uid) => warningUids.has(uid))).map((item) => item.group);
314
+ const selectionAvailable = applications.some((group) => groupKey(group) === selected);
315
+ require__global_external_react.useEffect(() => {
316
+ if (selected && !selectionAvailable) setSelected("");
317
+ }, [selected, selectionAvailable]);
200
318
  const application = applications.find((group) => groupKey(group) === selected);
201
319
  const uids = new Set(known.current.get(selected)?.uids ?? []);
202
- const warningIds = new Set((data?.events ?? []).filter((event) => event.type === "Warning").map((event) => event.metadata?.uid));
203
- const timeline = [...require_resource_diagnostics.normalizeEvents(data?.events ?? []), ...observed].filter((entry) => !!application && !!entry.objectUid && uids.has(entry.objectUid) && (!reason || `${entry.reason} ${entry.message}`.toLowerCase().includes(reason.toLowerCase())) && (!warningOnly || warningIds.has(entry.id))).sort((a, b) => (Date.parse(b.time ?? "") || 0) - (Date.parse(a.time ?? "") || 0));
320
+ const normalizedEvents = require_resource_diagnostics.normalizeEvents(data?.events ?? []);
321
+ const warningIds = new Set(normalizedEvents.filter((_entry, index) => data?.events?.[index]?.type === "Warning").map((entry) => entry.id));
322
+ const eventReferences = new Map(normalizedEvents.map((entry, index) => {
323
+ const event = data?.events?.[index];
324
+ return [entry.id, event?.involvedObject ?? event?.regarding];
325
+ }));
326
+ const timeline = [...normalizedEvents, ...observed].filter((entry) => (!application || !!entry.objectUid && uids.has(entry.objectUid)) && (!reason || `${entry.reason} ${entry.message}`.toLowerCase().includes(reason.toLowerCase())) && (!warningOnly || warningIds.has(entry.id))).sort((a, b) => (Date.parse(b.time ?? "") || 0) - (Date.parse(a.time ?? "") || 0));
204
327
  const pending = (data?.pods ?? []).filter((pod) => pod.status?.phase === "Pending");
328
+ const PendingCard = pending.length && data?.pods ? "button" : "div";
205
329
  const selectedPod = pending.find((pod) => pod.metadata.uid === pendingUid);
206
330
  const diagnosis = selectedPod ? require_resource_diagnostics.diagnosePendingPod(selectedPod, data?.nodes ?? [], data?.events ?? [], data?.pvcs) : void 0;
207
331
  return /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
208
332
  className: "power-diagnostics",
209
333
  style: {
210
- padding: 20,
334
+ padding: 24,
211
335
  overflow: "auto",
212
- height: "100%"
336
+ height: "100%",
337
+ minWidth: 0
213
338
  },
214
339
  children: [
215
- /* @__PURE__ */ require_jsx_runtime.jsx("style", { children: `.power-diagnostics table{width:100%;border-collapse:collapse}.power-diagnostics th,.power-diagnostics td{text-align:left;padding:9px;border-bottom:1px solid var(--borderColor);vertical-align:top}.power-diagnostics button,.power-diagnostics select,.power-diagnostics input{margin:4px;padding:6px}.power-diagnostics .toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.power-diagnostics small{display:block;opacity:.75}.power-diagnostics button{cursor:pointer;display:inline-flex;align-items:center;gap:6px;border-radius:4px;border:1px solid var(--borderColor);background:var(--contentColor);color:var(--textColorPrimary);font:inherit}.power-diagnostics button:hover{border-color:var(--primary)}.power-diagnostics button[aria-pressed=true]{color:var(--primary);border-color:var(--primary)}.power-diagnostics button:disabled{opacity:.5;cursor:default}.power-diagnostics select,.power-diagnostics input{border-radius:4px;border:1px solid var(--borderColor);background:var(--contentColor);color:var(--textColorPrimary);font:inherit}.power-diagnostics :is(button,select,input):focus-visible{outline:2px solid var(--primary);outline-offset:2px}.power-diagnostics input[type=checkbox]{accent-color:var(--primary)}.power-diagnostics th{color:var(--textColorSecondary);font-weight:500}.power-diagnostics nav{display:flex;gap:8px;flex-wrap:wrap}` }),
216
- /* @__PURE__ */ require_jsx_runtime.jsx("h2", { children: "Resource diagnostics" }),
340
+ /* @__PURE__ */ require_jsx_runtime.jsx("style", { children: require_diagnostics_css.diagnosticsStyles }),
341
+ /* @__PURE__ */ require_jsx_runtime.jsxs("header", {
342
+ className: "diagnostics-header",
343
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("h2", { children: "Resource diagnostics" }), /* @__PURE__ */ require_jsx_runtime.jsxs("span", {
344
+ className: "snapshot-meta",
345
+ children: ["Read-only snapshot", data ? ` · ${require_date_time.formatDateTime(data.time)}` : ""]
346
+ })]
347
+ }),
217
348
  /* @__PURE__ */ require_jsx_runtime.jsx("nav", {
218
349
  "aria-label": "Diagnostics views",
219
350
  children: [
@@ -225,319 +356,622 @@ function DiagnosticsPage() {
225
356
  title: `Show ${name.toLowerCase()}`,
226
357
  "aria-pressed": tab === name,
227
358
  onClick: () => setTab(name),
228
- children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: name === "Consumers" ? "account_tree" : name === "Timeline" ? "timeline" : "hourglass_empty" }), name]
359
+ children: [
360
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: name === "Consumers" ? "account_tree" : name === "Timeline" ? "timeline" : "hourglass_empty" }),
361
+ name,
362
+ name === "Pending" && data?.pods ? ` (${pending.length})` : ""
363
+ ]
229
364
  }, name))
230
365
  }),
231
- /* @__PURE__ */ require_jsx_runtime.jsxs("p", { children: ["Read-only cluster snapshot", data ? ` · ${new Date(data.time).toLocaleTimeString([], { hourCycle: "h23" })}` : " · Loading"] }),
232
- error && /* @__PURE__ */ require_jsx_runtime.jsx("p", {
366
+ error && /* @__PURE__ */ require_jsx_runtime.jsxs("p", {
367
+ className: "diagnostics-notice",
233
368
  role: "status",
234
- children: error
369
+ children: [error, ". Check the cluster connection and your access permissions."]
235
370
  }),
236
371
  data?.errors.map((message) => /* @__PURE__ */ require_jsx_runtime.jsx("p", {
372
+ className: "diagnostics-notice",
237
373
  role: "status",
238
374
  children: message
239
375
  }, message)),
240
- tab === "Consumers" && /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [
376
+ /* @__PURE__ */ require_jsx_runtime.jsxs("section", {
377
+ className: "view-intro",
378
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("h3", { children: viewDescriptions[tab][0] }), /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: viewDescriptions[tab][1] })]
379
+ }),
380
+ data && tab === "Consumers" && /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
381
+ className: "diagnostics-summary",
382
+ "aria-label": "Snapshot summary",
383
+ children: [
384
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
385
+ className: "summary-card workloads",
386
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", {
387
+ className: "summary-icon",
388
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
389
+ material: "account_tree",
390
+ size: 22
391
+ })
392
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("strong", { children: data.pods ? groups.length : "Unavailable" }), /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "Workloads and standalone pods" })] })]
393
+ }),
394
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
395
+ className: "summary-card pods",
396
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", {
397
+ className: "summary-icon",
398
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
399
+ material: "view_in_ar",
400
+ size: 22
401
+ })
402
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("strong", { children: data.pods?.length ?? "Unavailable" }), /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "Pods in snapshot" })] })]
403
+ }),
404
+ /* @__PURE__ */ require_jsx_runtime.jsxs(PendingCard, {
405
+ className: `summary-card pending${!data.pods ? " unavailable" : pending.length ? " attention" : ""}`,
406
+ ...pending.length ? {
407
+ type: "button",
408
+ title: "Inspect pending pods",
409
+ "aria-label": "Inspect pending pods",
410
+ onClick: () => {
411
+ setPendingUid(pending[0]?.metadata.uid ?? "");
412
+ setTab("Pending");
413
+ }
414
+ } : {},
415
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", {
416
+ className: "summary-icon",
417
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
418
+ material: "hourglass_empty",
419
+ size: 22
420
+ })
421
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("strong", { children: data.pods ? pending.length : "Unavailable" }), /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "Pending pods" })] })]
422
+ })
423
+ ]
424
+ }),
425
+ !data && !error && /* @__PURE__ */ require_jsx_runtime.jsx("p", {
426
+ className: "diagnostics-empty",
427
+ role: "status",
428
+ children: "Loading resource diagnostics…"
429
+ }),
430
+ tab === "Consumers" && data && /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [
241
431
  /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
242
- className: "toolbar",
432
+ className: "toolbar consumers-toolbar",
243
433
  children: [
244
434
  /* @__PURE__ */ require_jsx_runtime.jsxs("label", { children: [
245
435
  "Group by",
246
436
  " ",
247
- /* @__PURE__ */ require_jsx_runtime.jsxs("select", {
248
- "aria-label": "Group consumers",
437
+ /* @__PURE__ */ require_jsx_runtime.jsx(DiagnosticsSelect, {
438
+ label: "Group consumers",
249
439
  value: groupMode,
250
- onChange: (event) => setGroupMode(event.target.value),
251
- children: [/* @__PURE__ */ require_jsx_runtime.jsx("option", {
440
+ onChange: setGroupMode,
441
+ options: [{
252
442
  value: "workload",
253
- children: "Workload"
254
- }), /* @__PURE__ */ require_jsx_runtime.jsx("option", {
443
+ label: "Workload"
444
+ }, {
255
445
  value: "namespace",
256
- children: "Namespace"
257
- })]
446
+ label: "Namespace"
447
+ }]
258
448
  })
259
449
  ] }),
260
- /* @__PURE__ */ require_jsx_runtime.jsx("input", {
261
- "aria-label": "Filter consumers",
262
- placeholder: "Namespace or workload",
263
- value: filter,
264
- onChange: (event) => setFilter(event.target.value)
450
+ /* @__PURE__ */ require_jsx_runtime.jsxs("label", {
451
+ className: "search-field",
452
+ children: ["Search consumers", /* @__PURE__ */ require_jsx_runtime.jsx("span", {
453
+ className: "diagnostics-input",
454
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Input, {
455
+ "aria-label": "Filter consumers",
456
+ placeholder: "Namespace or workload",
457
+ value: filter,
458
+ onChange: setFilter
459
+ })
460
+ })]
265
461
  }),
266
462
  /* @__PURE__ */ require_jsx_runtime.jsxs("label", { children: [
267
463
  "Sort",
268
464
  " ",
269
- /* @__PURE__ */ require_jsx_runtime.jsxs("select", {
270
- "aria-label": "Sort consumers",
465
+ /* @__PURE__ */ require_jsx_runtime.jsx(DiagnosticsSelect, {
466
+ label: "Sort consumers",
271
467
  value: sort,
272
- onChange: (event) => setSort(event.target.value),
273
- children: [
274
- /* @__PURE__ */ require_jsx_runtime.jsx("option", {
468
+ onChange: setSort,
469
+ options: [
470
+ {
275
471
  value: "cpu",
276
- children: "CPU usage"
277
- }),
278
- /* @__PURE__ */ require_jsx_runtime.jsx("option", {
472
+ label: "CPU usage"
473
+ },
474
+ {
279
475
  value: "memory",
280
- children: "Memory usage"
281
- }),
282
- /* @__PURE__ */ require_jsx_runtime.jsx("option", {
476
+ label: "Memory usage"
477
+ },
478
+ {
283
479
  value: "requests",
284
- children: "CPU requests"
285
- }),
286
- /* @__PURE__ */ require_jsx_runtime.jsx("option", {
480
+ label: "CPU requests"
481
+ },
482
+ {
287
483
  value: "memoryRequests",
288
- children: "Memory requests"
289
- }),
290
- /* @__PURE__ */ require_jsx_runtime.jsx("option", {
484
+ label: "Memory requests"
485
+ },
486
+ {
291
487
  value: "name",
292
- children: "Namespace / name"
293
- })
488
+ label: "Namespace / name"
489
+ }
294
490
  ]
295
491
  })
296
- ] })
492
+ ] }),
493
+ /* @__PURE__ */ require_jsx_runtime.jsx("div", {
494
+ className: "warning-filter",
495
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Checkbox, {
496
+ label: "Needs attention",
497
+ value: needsAttention,
498
+ onChange: setNeedsAttention
499
+ })
500
+ })
297
501
  ]
298
502
  }),
299
- /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Usage coverage is per resource. Missing metrics are unavailable. Unscheduled requests are listed separately." }),
300
- /* @__PURE__ */ require_jsx_runtime.jsxs("table", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("thead", { children: /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
301
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Namespace / consumer" }),
302
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "CPU" }),
303
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Memory" }),
304
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Unscheduled requests" })
305
- ] }) }), /* @__PURE__ */ require_jsx_runtime.jsx("tbody", { children: (groupMode === "namespace" ? [...new Set(filtered.map((group) => group.namespace))] : [""]).map((namespace) => /* @__PURE__ */ require_jsx_runtime.jsx(NamespaceRows, {
306
- namespace,
307
- groups: namespace ? filtered.filter((group) => group.namespace === namespace) : filtered,
308
- clusterId: data?.clusterId ?? "",
309
- usage: projected?.usage ?? [],
310
- viewHistory: setHistoryTarget,
311
- open: !namespace || namespacesOpen.includes(namespace),
312
- toggleNamespace: () => setNamespacesOpen((items) => items.includes(namespace) ? items.filter((item) => item !== namespace) : [...items, namespace]),
313
- expanded,
314
- toggleGroup: (key) => setExpanded((items) => items.includes(key) ? items.filter((item) => item !== key) : [...items, key])
315
- }, namespace)) })] }),
316
- !filtered.length && /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "No consumers available" }),
317
- data && historyTarget && /* @__PURE__ */ require_jsx_runtime.jsx(ApplicationHistory, {
318
- data,
319
- group: groups.find((group) => groupKey(group) === historyTarget)
320
- }, `${data.clusterId}/${historyTarget}`)
503
+ /* @__PURE__ */ require_jsx_runtime.jsxs("details", {
504
+ className: "diagnostics-explainer",
505
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "How to read usage and requests" }), /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Usage is measured consumption. Requests are configured resource reservations. Coverage is reported separately for CPU and memory; missing metrics are unavailable, never zero. Requests from unscheduled pods appear separately." })]
506
+ }),
507
+ /* @__PURE__ */ require_jsx_runtime.jsx("div", {
508
+ className: "diagnostics-table",
509
+ children: /* @__PURE__ */ require_jsx_runtime.jsxs("table", {
510
+ className: "consumers-table",
511
+ children: [
512
+ /* @__PURE__ */ require_jsx_runtime.jsxs("colgroup", { children: [
513
+ /* @__PURE__ */ require_jsx_runtime.jsx("col", { className: "consumer-column" }),
514
+ /* @__PURE__ */ require_jsx_runtime.jsx("col", { className: "metric-column" }),
515
+ /* @__PURE__ */ require_jsx_runtime.jsx("col", { className: "metric-column" }),
516
+ /* @__PURE__ */ require_jsx_runtime.jsx("col", { className: "unscheduled-column" })
517
+ ] }),
518
+ /* @__PURE__ */ require_jsx_runtime.jsx("thead", { children: /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
519
+ /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Namespace / consumer" }),
520
+ /* @__PURE__ */ require_jsx_runtime.jsx("th", {
521
+ className: "numeric",
522
+ children: "CPU usage / requests"
523
+ }),
524
+ /* @__PURE__ */ require_jsx_runtime.jsx("th", {
525
+ className: "numeric",
526
+ children: "Memory usage / requests"
527
+ }),
528
+ /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Unscheduled requests" })
529
+ ] }) }),
530
+ /* @__PURE__ */ require_jsx_runtime.jsx("tbody", { children: (groupMode === "namespace" ? [...new Set(filtered.map((group) => group.namespace))] : [""]).map((namespace) => /* @__PURE__ */ require_jsx_runtime.jsx(NamespaceRows, {
531
+ namespace,
532
+ groups: namespace ? filtered.filter((group) => group.namespace === namespace) : filtered,
533
+ clusterId: data?.clusterId ?? "",
534
+ usage: projected?.usage ?? [],
535
+ open: !namespace || namespacesOpen.includes(namespace),
536
+ toggleNamespace: () => setNamespacesOpen((items) => items.includes(namespace) ? items.filter((item) => item !== namespace) : [...items, namespace]),
537
+ expanded,
538
+ toggleGroup: (key) => setExpanded((items) => items.includes(key) ? items.filter((item) => item !== key) : [...items, key])
539
+ }, namespace)) })
540
+ ]
541
+ })
542
+ }),
543
+ !filtered.length && (!data.pods ? /* @__PURE__ */ require_jsx_runtime.jsx("p", {
544
+ className: "diagnostics-empty",
545
+ children: "Pod inventory unavailable"
546
+ }) : filter ? /* @__PURE__ */ require_jsx_runtime.jsx("p", {
547
+ className: "diagnostics-empty",
548
+ children: "No consumers match this filter"
549
+ }) : needsAttention && groups.length ? /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
550
+ className: `diagnostics-empty attention-empty ${groups.every((group) => consumerStatus(group.pods).tone === "healthy") ? "all-ready" : "readiness-unconfirmed"}`,
551
+ children: [
552
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
553
+ material: groups.every((group) => consumerStatus(group.pods).tone === "healthy") ? "check_circle_outline" : "info_outline",
554
+ size: 22
555
+ }),
556
+ /* @__PURE__ */ require_jsx_runtime.jsx("strong", { children: groups.every((group) => consumerStatus(group.pods).tone === "healthy") ? "All consumers are ready" : "No known issues" }),
557
+ /* @__PURE__ */ require_jsx_runtime.jsx("small", { children: groups.every((group) => consumerStatus(group.pods).tone === "healthy") ? "No pending pods or known failures in this snapshot." : "Unconfirmed readiness is not treated as a failure. Show all consumers to inspect them." }),
558
+ /* @__PURE__ */ require_jsx_runtime.jsx("button", {
559
+ type: "button",
560
+ onClick: () => setNeedsAttention(false),
561
+ children: "Show all consumers"
562
+ })
563
+ ]
564
+ }) : /* @__PURE__ */ require_jsx_runtime.jsx("p", {
565
+ className: "diagnostics-empty",
566
+ children: "No consumers available"
567
+ }))
321
568
  ] }),
322
- tab === "Timeline" && /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [
569
+ tab === "Timeline" && data && /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [
323
570
  /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
324
- className: "toolbar",
571
+ className: "toolbar timeline-toolbar",
325
572
  children: [
326
573
  /* @__PURE__ */ require_jsx_runtime.jsxs("label", { children: [
327
574
  "Application",
328
575
  " ",
329
- /* @__PURE__ */ require_jsx_runtime.jsxs("select", {
330
- "aria-label": "Timeline application",
331
- value: selected,
332
- onChange: (event) => setSelected(event.target.value),
333
- children: [/* @__PURE__ */ require_jsx_runtime.jsx("option", {
576
+ /* @__PURE__ */ require_jsx_runtime.jsx(DiagnosticsSelect, {
577
+ label: "Timeline application",
578
+ value: selectionAvailable ? selected : "",
579
+ onChange: setSelected,
580
+ options: [{
334
581
  value: "",
335
- children: "Select a workload or standalone pod"
336
- }), applications.map((group) => /* @__PURE__ */ require_jsx_runtime.jsxs("option", {
582
+ label: "All applications"
583
+ }, ...applications.map((group) => ({
337
584
  value: groupKey(group),
338
- children: [
339
- group.namespace,
340
- " / ",
341
- group.kind,
342
- " / ",
343
- group.name
344
- ]
345
- }, groupKey(group)))]
585
+ label: `${group.namespace} / ${group.kind} / ${group.name}`
586
+ }))]
346
587
  })
347
588
  ] }),
348
- /* @__PURE__ */ require_jsx_runtime.jsx("input", {
349
- "aria-label": "Filter timeline reason",
350
- placeholder: "Reason or message",
351
- value: reason,
352
- onChange: (event) => setReason(event.target.value)
589
+ /* @__PURE__ */ require_jsx_runtime.jsxs("label", {
590
+ className: "search-field",
591
+ children: ["Search events", /* @__PURE__ */ require_jsx_runtime.jsx("span", {
592
+ className: "diagnostics-input",
593
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Input, {
594
+ "aria-label": "Filter timeline reason",
595
+ placeholder: "Reason or message",
596
+ value: reason,
597
+ onChange: setReason
598
+ })
599
+ })]
353
600
  }),
354
- /* @__PURE__ */ require_jsx_runtime.jsxs("label", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("input", {
355
- type: "checkbox",
356
- checked: warningOnly,
357
- onChange: (event) => setWarningOnly(event.target.checked)
358
- }), "Warnings only"] })
601
+ /* @__PURE__ */ require_jsx_runtime.jsx("div", {
602
+ className: "warning-filter",
603
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Checkbox, {
604
+ label: "Warnings only",
605
+ value: warningOnly,
606
+ onChange: setWarningOnly
607
+ })
608
+ })
359
609
  ]
360
610
  }),
361
- /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Kubernetes events have limited retention. Observed changes begin with this open view, retain at most 300 entries, and have unknown transition times between snapshots. Related identities observed in this view are retained for at most 100 applications and 500 identities per application; older identity coverage can be incomplete." }),
362
- /* @__PURE__ */ require_jsx_runtime.jsxs("table", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("thead", { children: /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
363
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Time / certainty" }),
364
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Reason" }),
365
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Evidence" })
366
- ] }) }), /* @__PURE__ */ require_jsx_runtime.jsx("tbody", { children: timeline.map((entry) => /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
367
- /* @__PURE__ */ require_jsx_runtime.jsxs("td", { children: [entry.time ? new Date(entry.time).toLocaleString([], { hourCycle: "h23" }) : "Time unknown", /* @__PURE__ */ require_jsx_runtime.jsxs("small", { children: [
368
- entry.certainty,
369
- ", count ",
370
- entry.count,
371
- entry.firstTime ? `, first ${new Date(entry.firstTime).toLocaleString([], { hourCycle: "h23" })}` : ""
372
- ] })] }),
373
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: entry.reason }),
374
- /* @__PURE__ */ require_jsx_runtime.jsxs("td", { children: [
375
- entry.message,
376
- (() => {
377
- const object = entry.objectUid ? projected?.objects.get(entry.objectUid) : void 0;
378
- return object && data ? /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
379
- type: "button",
380
- title: "Open exact resource details",
381
- onClick: () => openResource(object, data.clusterId),
382
- children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: "open_in_new" }), "Open resource"]
383
- }) : null;
384
- })(),
385
- /* @__PURE__ */ require_jsx_runtime.jsx("small", { children: entry.gap })
386
- ] })
387
- ] }, entry.id)) })] }),
388
- !timeline.length && /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: application ? "No matching retained events or observed changes" : "Select an application to inspect its exact resource identities" })
611
+ /* @__PURE__ */ require_jsx_runtime.jsxs("details", {
612
+ className: "diagnostics-explainer",
613
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "Timeline coverage and timing" }), /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Kubernetes events have limited retention. Observed changes begin with this open view, retain at most 300 entries, and have unknown transition times between snapshots. Related identities observed in this view are retained for at most 100 applications and 500 identities per application; older identity coverage can be incomplete." })]
614
+ }),
615
+ /* @__PURE__ */ require_jsx_runtime.jsx("div", {
616
+ className: "timeline-legend",
617
+ "aria-label": "Event types",
618
+ children: [
619
+ "Warning",
620
+ "Rollout",
621
+ "Restart",
622
+ "Readiness",
623
+ "Kubernetes event",
624
+ "Observed change"
625
+ ].map((label) => /* @__PURE__ */ require_jsx_runtime.jsx("span", {
626
+ className: `timeline-type ${eventCategory(label)}`,
627
+ children: label
628
+ }, label))
629
+ }),
630
+ /* @__PURE__ */ require_jsx_runtime.jsx("ol", {
631
+ className: "diagnostics-timeline",
632
+ "aria-label": "Workload event timeline",
633
+ children: timeline.map((entry) => {
634
+ const kind = eventCategory(entry.reason);
635
+ const category = warningIds.has(entry.id) ? "warning" : kind === "event" && entry.certainty === "observed" ? "observed" : kind;
636
+ const label = category === "warning" ? "Warning" : category === "rollout" ? "Rollout" : category === "restart" ? "Restart" : category === "readiness" ? "Readiness" : entry.certainty === "observed" ? "Observed change" : "Kubernetes event";
637
+ const object = entry.objectUid ? projected?.objects.get(entry.objectUid) : void 0;
638
+ const reference = eventReferences.get(entry.id);
639
+ const referenceKind = object?.kind ?? reference?.kind;
640
+ const metadata = object?.metadata ?? reference;
641
+ return /* @__PURE__ */ require_jsx_runtime.jsxs("li", {
642
+ className: `timeline-entry ${category}`,
643
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
644
+ className: "timeline-time",
645
+ children: [entry.time ? /* @__PURE__ */ require_jsx_runtime.jsx("time", {
646
+ dateTime: entry.time,
647
+ children: require_date_time.formatDateTime(entry.time)
648
+ }) : "Time unknown", /* @__PURE__ */ require_jsx_runtime.jsx("small", { children: entry.certainty === "observed" ? "Observed at snapshot" : "Kubernetes event time" })]
649
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
650
+ className: "timeline-content",
651
+ children: [
652
+ object && data && /* @__PURE__ */ require_jsx_runtime.jsx("button", {
653
+ type: "button",
654
+ className: "timeline-resource-action",
655
+ "aria-label": "Open resource",
656
+ title: `Open ${object.kind ?? "Pod"} ${object.metadata.namespace} / ${object.metadata.name}`,
657
+ onClick: (event) => openResource(object, data.clusterId, event),
658
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: "open_in_new" })
659
+ }),
660
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
661
+ className: "timeline-card-heading",
662
+ children: [
663
+ " ",
664
+ /* @__PURE__ */ require_jsx_runtime.jsx("span", {
665
+ className: `timeline-type ${category}`,
666
+ children: label
667
+ }),
668
+ /* @__PURE__ */ require_jsx_runtime.jsx("h4", { children: entry.reason }),
669
+ /* @__PURE__ */ require_jsx_runtime.jsxs("small", {
670
+ className: "timeline-resource-identity",
671
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
672
+ material: referenceKind === "Pod" ? "view_in_ar" : "account_tree",
673
+ size: 12
674
+ }), metadata?.name ? `${metadata.namespace ?? "Namespace unknown"} / ${referenceKind ?? "Resource"} / ${metadata.name}` : "Resource identity unavailable"]
675
+ })
676
+ ]
677
+ }),
678
+ /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: entry.message }),
679
+ /* @__PURE__ */ require_jsx_runtime.jsxs("small", { children: [
680
+ entry.certainty === "reported" ? "Reported" : entry.certainty === "observed" ? "Observed" : "Unknown",
681
+ " ",
682
+ "· Count ",
683
+ entry.count,
684
+ entry.firstTime ? ` · First ${require_date_time.formatDateTime(entry.firstTime)}` : ""
685
+ ] }),
686
+ entry.gap && /* @__PURE__ */ require_jsx_runtime.jsx("small", { children: entry.gap })
687
+ ]
688
+ })]
689
+ }, entry.id);
690
+ })
691
+ }),
692
+ !timeline.length && /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
693
+ className: "diagnostics-empty",
694
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("p", { children: warningOnly ? "No retained warning events match these filters" : "No retained events or observed changes match these filters" }), warningOnly && /* @__PURE__ */ require_jsx_runtime.jsx("button", {
695
+ type: "button",
696
+ onClick: () => setWarningOnly(false),
697
+ children: "Show all events"
698
+ })]
699
+ })
389
700
  ] }),
390
- tab === "Pending" && /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [/* @__PURE__ */ require_jsx_runtime.jsxs("label", { children: [
701
+ tab === "Pending" && data && /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [/* @__PURE__ */ require_jsx_runtime.jsxs("label", { children: [
391
702
  "Pending pod",
392
703
  " ",
393
- /* @__PURE__ */ require_jsx_runtime.jsxs("select", {
394
- "aria-label": "Pending pod",
704
+ /* @__PURE__ */ require_jsx_runtime.jsx(DiagnosticsSelect, {
705
+ label: "Pending pod",
395
706
  value: pendingUid,
396
- onChange: (event) => setPendingUid(event.target.value),
397
- children: [/* @__PURE__ */ require_jsx_runtime.jsx("option", {
707
+ onChange: setPendingUid,
708
+ options: [{
398
709
  value: "",
399
- children: "Select a pod"
400
- }), pending.map((pod) => /* @__PURE__ */ require_jsx_runtime.jsxs("option", {
401
- value: pod.metadata.uid,
402
- children: [
403
- pod.metadata.namespace,
404
- " / ",
405
- pod.metadata.name
406
- ]
407
- }, pod.metadata.uid))]
710
+ label: "Select a pod"
711
+ }, ...pending.map((pod) => ({
712
+ value: pod.metadata.uid ?? "",
713
+ label: `${pod.metadata.namespace} / ${pod.metadata.name}`
714
+ }))]
408
715
  })
409
716
  ] }), selectedPod && diagnosis ? /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [
410
- /* @__PURE__ */ require_jsx_runtime.jsx("h3", { children: diagnosis.state === "assigned-waiting" ? "Assigned and waiting" : "Unscheduled" }),
411
- /* @__PURE__ */ require_jsx_runtime.jsxs("p", { children: [
412
- "Requested CPU: ",
413
- podRequest(selectedPod, "cpu"),
414
- " · Requested memory: ",
415
- podRequest(selectedPod, "memory")
416
- ] }),
417
- /* @__PURE__ */ require_jsx_runtime.jsxs("p", { children: [
418
- "Node selector:",
419
- " ",
420
- Object.entries(selectedPod.spec?.nodeSelector ?? {}).map(([key, value]) => `${key}=${value}`).join(", ") || "None"
421
- ] }),
422
- /* @__PURE__ */ require_jsx_runtime.jsxs("p", { children: [
423
- "Tolerations:",
424
- " ",
425
- (selectedPod.spec?.tolerations ?? []).map((item) => `${item.key || "all keys"} ${item.operator ?? "Equal"}${item.value ? ` ${item.value}` : ""} (${item.effect || "all effects"})`).join(", ") || "None"
426
- ] }),
427
- /* @__PURE__ */ require_jsx_runtime.jsxs("p", { children: [
428
- "Required node affinity:",
429
- " ",
430
- selectedPod.spec?.affinity?.nodeAffinity?.requiredDuringSchedulingIgnoredDuringExecution ? JSON.stringify(selectedPod.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution).slice(0, 2e3) : "None"
431
- ] }),
432
- /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
433
- type: "button",
434
- title: "Open pod details",
435
- onClick: () => openResource(selectedPod, data.clusterId),
436
- children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: "open_in_new" }), "Open pod"]
717
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
718
+ className: `pending-heading ${consumerStatus([selectedPod]).tone}`,
719
+ children: [
720
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
721
+ className: "pending-title-row",
722
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsxs("strong", { children: [
723
+ selectedPod.metadata.namespace,
724
+ " / ",
725
+ selectedPod.metadata.name
726
+ ] }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
727
+ className: "pending-state-row",
728
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("h3", { children: diagnosis.state === "assigned-waiting" ? "Assigned and waiting" : "Unscheduled" }), consumerStatus([selectedPod]).tone === "error" && /* @__PURE__ */ require_jsx_runtime.jsx(ConsumerStatus, { pods: [selectedPod] })]
729
+ })] }), /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
730
+ className: "pending-open-action",
731
+ type: "button",
732
+ title: "Open pod details",
733
+ onClick: (event) => openResource(selectedPod, data.clusterId, event),
734
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
735
+ material: "open_in_new",
736
+ size: 15
737
+ }), "Open pod"]
738
+ })]
739
+ }),
740
+ /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: diagnosis.state === "assigned-waiting" ? "A node is assigned. Check pod conditions and events for startup or storage issues." : "No node is assigned. Start with scheduler events, then inspect constraints." }),
741
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
742
+ className: "pending-request-badges",
743
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("span", { children: [
744
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
745
+ material: "memory",
746
+ size: 14
747
+ }),
748
+ "CPU request ",
749
+ /* @__PURE__ */ require_jsx_runtime.jsx("strong", { children: podRequest(selectedPod, "cpu") })
750
+ ] }), /* @__PURE__ */ require_jsx_runtime.jsxs("span", { children: [
751
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
752
+ material: "storage",
753
+ size: 14
754
+ }),
755
+ "Memory request ",
756
+ /* @__PURE__ */ require_jsx_runtime.jsx("strong", { children: podRequest(selectedPod, "memory") })
757
+ ] })]
758
+ })
759
+ ]
760
+ }),
761
+ /* @__PURE__ */ require_jsx_runtime.jsxs("details", {
762
+ className: "diagnostics-explainer",
763
+ children: [
764
+ /* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "Scheduling constraints and pod conditions" }),
765
+ /* @__PURE__ */ require_jsx_runtime.jsxs("p", { children: [
766
+ "Node selector:",
767
+ " ",
768
+ Object.entries(selectedPod.spec?.nodeSelector ?? {}).map(([key, value]) => `${key}=${value}`).join(", ") || "None"
769
+ ] }),
770
+ /* @__PURE__ */ require_jsx_runtime.jsxs("p", { children: [
771
+ "Tolerations:",
772
+ " ",
773
+ (selectedPod.spec?.tolerations ?? []).map((item) => `${item.key || "all keys"} ${item.operator ?? "Equal"}${item.value ? ` ${item.value}` : ""} (${item.effect || "all effects"})`).join(", ") || "None"
774
+ ] }),
775
+ /* @__PURE__ */ require_jsx_runtime.jsxs("p", { children: [
776
+ "Required node affinity:",
777
+ " ",
778
+ selectedPod.spec?.affinity?.nodeAffinity?.requiredDuringSchedulingIgnoredDuringExecution ? JSON.stringify(selectedPod.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution).slice(0, 2e3) : "None"
779
+ ] }),
780
+ /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: selectedPod.status?.conditions?.map((condition) => `${condition.type}: ${condition.status}${condition.message ? ` (${condition.message})` : ""}`).join(" · ") })
781
+ ]
782
+ }),
783
+ /* @__PURE__ */ require_jsx_runtime.jsx("h3", { children: "Scheduling evidence" }),
784
+ /* @__PURE__ */ require_jsx_runtime.jsx("div", {
785
+ className: "diagnostics-table",
786
+ children: /* @__PURE__ */ require_jsx_runtime.jsxs("table", {
787
+ className: "evidence-table",
788
+ children: [
789
+ /* @__PURE__ */ require_jsx_runtime.jsxs("colgroup", { children: [
790
+ /* @__PURE__ */ require_jsx_runtime.jsx("col", { className: "evidence-source" }),
791
+ /* @__PURE__ */ require_jsx_runtime.jsx("col", { className: "evidence-node" }),
792
+ /* @__PURE__ */ require_jsx_runtime.jsx("col", { className: "evidence-finding" })
793
+ ] }),
794
+ /* @__PURE__ */ require_jsx_runtime.jsx("thead", { children: /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
795
+ /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Evidence source" }),
796
+ /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Node" }),
797
+ /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Finding" })
798
+ ] }) }),
799
+ /* @__PURE__ */ require_jsx_runtime.jsx("tbody", { children: diagnosis.evidence.map((entry, index) => /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
800
+ /* @__PURE__ */ require_jsx_runtime.jsxs("td", { children: [/* @__PURE__ */ require_jsx_runtime.jsxs("span", {
801
+ className: `evidence-badge ${entry.source === "event" ? "reported" : "inferred"}`,
802
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
803
+ material: entry.source === "event" ? "receipt_long" : "rule",
804
+ size: 13
805
+ }), entry.source === "event" ? "Reported" : "Inferred"]
806
+ }), /* @__PURE__ */ require_jsx_runtime.jsx("small", { children: entry.source === "event" ? "Reported Kubernetes event" : "Local hard constraint" })] }),
807
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: entry.node ?? "—" }),
808
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: entry.message })
809
+ ] }, `${entry.node}/${index}`)) })
810
+ ]
811
+ })
437
812
  }),
438
- /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: selectedPod.status?.conditions?.map((condition) => `${condition.type}: ${condition.status}${condition.message ? ` (${condition.message})` : ""}`).join(" · ") }),
439
- /* @__PURE__ */ require_jsx_runtime.jsxs("table", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("thead", { children: /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
440
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Evidence source" }),
441
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Node" }),
442
- /* @__PURE__ */ require_jsx_runtime.jsx("th", { children: "Finding" })
443
- ] }) }), /* @__PURE__ */ require_jsx_runtime.jsx("tbody", { children: diagnosis.evidence.map((entry, index) => /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
444
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: entry.source === "event" ? "Reported Kubernetes event" : "Local hard constraint" }),
445
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: entry.node ?? "—" }),
446
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: entry.message })
447
- ] }, `${entry.node}/${index}`)) })] }),
448
813
  !diagnosis.evidence.length && /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "No retained evidence is available for this pod" }),
449
- diagnosis.limitations.map((message) => /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: message }, message))
450
- ] }) : /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: pending.length ? "Select a pending pod" : "No pending pods available" })] })
814
+ /* @__PURE__ */ require_jsx_runtime.jsxs("details", {
815
+ className: "diagnostics-explainer",
816
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "What this diagnosis can establish" }), diagnosis.limitations.map((message) => /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: message }, message))]
817
+ })
818
+ ] }) : /* @__PURE__ */ require_jsx_runtime.jsx("p", {
819
+ className: "diagnostics-empty",
820
+ children: !data.pods ? "Pod inventory unavailable. Check cluster access before investigating pending pods." : pending.length ? "Select a pending pod to see scheduling evidence and requests" : "No pending pods in this snapshot"
821
+ })] })
451
822
  ]
452
823
  });
453
824
  }
454
- function ConsumerRows({ group, clusterId, expanded, toggle, usage, viewHistory }) {
455
- return /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [/* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
456
- /* @__PURE__ */ require_jsx_runtime.jsxs("td", { children: [
457
- /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
458
- type: "button",
459
- title: expanded ? "Collapse pods" : "Expand pods",
460
- "aria-expanded": expanded,
461
- onClick: toggle,
462
- children: [
463
- /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: expanded ? "expand_less" : "expand_more" }),
464
- group.namespace,
465
- " / ",
466
- group.kind,
467
- " / ",
468
- group.name
469
- ]
825
+ function ConsumerRows({ group, clusterId, expanded, toggle, usage, depth }) {
826
+ return /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [/* @__PURE__ */ require_jsx_runtime.jsxs("tr", {
827
+ className: `consumer-workload-row consumer-depth-${depth} consumer-tone-${consumerStatus(group.pods).tone}`,
828
+ "data-row-depth": depth,
829
+ children: [
830
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
831
+ className: "consumer-identity-row",
832
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
833
+ className: "consumer-identity-main",
834
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
835
+ className: "consumer-title-line",
836
+ children: [group.ownerResolved && resources[group.kind] && group.name !== "Unknown" ? /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
837
+ className: "consumer-resource-link",
838
+ type: "button",
839
+ title: `Open ${group.kind} ${group.namespace} / ${group.name}`,
840
+ onClick: (event) => openResource({
841
+ kind: group.kind,
842
+ metadata: {
843
+ uid: group.identity,
844
+ namespace: group.namespace,
845
+ name: group.name
846
+ }
847
+ }, clusterId, event),
848
+ children: [group.name, /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
849
+ material: "open_in_new",
850
+ size: 13
851
+ })]
852
+ }) : /* @__PURE__ */ require_jsx_runtime.jsx("span", {
853
+ className: "consumer-identity-label",
854
+ children: group.name
855
+ }), /* @__PURE__ */ require_jsx_runtime.jsx(ConsumerStatus, { pods: group.pods })]
856
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("small", {
857
+ className: "consumer-subtitle",
858
+ children: [
859
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
860
+ material: "folder_open",
861
+ size: 12
862
+ }),
863
+ group.namespace,
864
+ /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "·" }),
865
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
866
+ material: group.kind === "Pod" ? "view_in_ar" : "account_tree",
867
+ size: 12
868
+ }),
869
+ group.kind,
870
+ /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "·" }),
871
+ group.pods.length,
872
+ " pods",
873
+ group.ownerResolved ? "" : " · Owner chain incomplete"
874
+ ]
875
+ })]
876
+ }), /* @__PURE__ */ require_jsx_runtime.jsx("div", {
877
+ className: "consumer-row-actions",
878
+ children: /* @__PURE__ */ require_jsx_runtime.jsx("span", {
879
+ className: "consumer-expand-slot",
880
+ children: /* @__PURE__ */ require_jsx_runtime.jsx("button", {
881
+ className: "consumer-expand",
882
+ type: "button",
883
+ title: expanded ? "Collapse pods" : "Expand pods",
884
+ "aria-label": `${expanded ? "Collapse" : "Expand"} pods for ${group.name}`,
885
+ "aria-expanded": expanded,
886
+ onClick: toggle,
887
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: expanded ? "expand_less" : "expand_more" })
888
+ })
889
+ })
890
+ })]
891
+ }) }),
892
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
893
+ className: "numeric",
894
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(ResourceCell, {
895
+ summary: group.cpu,
896
+ metric: "cpu"
897
+ })
470
898
  }),
471
- /* @__PURE__ */ require_jsx_runtime.jsxs("small", { children: [
472
- group.pods.length,
473
- " pods",
474
- group.ownerResolved ? "" : " · Owner chain incomplete"
475
- ] }),
476
- /* @__PURE__ */ require_jsx_runtime.jsx(TrackButton, { identity: {
477
- clusterId,
478
- scope: group.kind === "Pod" ? "pod" : "workload",
479
- uid: group.identity
480
- } }),
481
- /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
482
- type: "button",
483
- title: "View resource history",
484
- onClick: () => viewHistory(groupKey(group)),
485
- children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: "timeline" }), "View history"]
899
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
900
+ className: "numeric",
901
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(ResourceCell, {
902
+ summary: group.memory,
903
+ metric: "memory"
904
+ })
905
+ }),
906
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
907
+ className: "numeric",
908
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(UnscheduledCell, {
909
+ cpu: group.cpu,
910
+ memory: group.memory
911
+ })
486
912
  })
487
- ] }),
488
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: summaryText(group.cpu, "cpu") }),
489
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: summaryText(group.memory, "memory") }),
490
- /* @__PURE__ */ require_jsx_runtime.jsxs("td", { children: [
491
- unscheduledText(group.cpu, "cpu"),
492
- " / ",
493
- unscheduledText(group.memory, "memory")
494
- ] })
495
- ] }), expanded && group.pods.map((pod) => /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
496
- /* @__PURE__ */ require_jsx_runtime.jsxs("td", { children: [
497
- /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
498
- type: "button",
499
- title: "Open pod details",
500
- onClick: () => openResource(pod, clusterId),
501
- children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: "open_in_new" }), pod.metadata.name]
913
+ ]
914
+ }), expanded && group.pods.map((pod) => /* @__PURE__ */ require_jsx_runtime.jsxs("tr", {
915
+ className: `consumer-pod-row consumer-depth-${depth + 1} consumer-tone-${consumerStatus([pod]).tone}`,
916
+ "data-row-depth": depth + 1,
917
+ children: [
918
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: /* @__PURE__ */ require_jsx_runtime.jsx("div", {
919
+ className: "consumer-identity-row",
920
+ children: /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
921
+ className: "consumer-identity-main",
922
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
923
+ className: "consumer-title-line",
924
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("button", {
925
+ className: "consumer-resource-link",
926
+ type: "button",
927
+ title: "Open pod details",
928
+ onClick: (event) => openResource(pod, clusterId, event),
929
+ children: [
930
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
931
+ material: "view_in_ar",
932
+ size: 14
933
+ }),
934
+ pod.metadata.name,
935
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
936
+ material: "open_in_new",
937
+ size: 12
938
+ })
939
+ ]
940
+ }), /* @__PURE__ */ require_jsx_runtime.jsx(ConsumerStatus, { pods: [pod] })]
941
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("small", {
942
+ className: "consumer-subtitle",
943
+ children: [
944
+ pod.status?.phase ?? "Unknown",
945
+ /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "·" }),
946
+ pod.spec?.nodeName ? `Node ${pod.spec.nodeName}` : "No node assigned"
947
+ ]
948
+ })]
949
+ })
950
+ }) }),
951
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
952
+ className: "numeric",
953
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(ResourceCell, {
954
+ summary: podResourceGroup(pod, usage).cpu,
955
+ metric: "cpu"
956
+ })
502
957
  }),
503
- " ",
504
- pod.metadata.uid && /* @__PURE__ */ require_jsx_runtime.jsx(TrackButton, { identity: {
505
- clusterId,
506
- scope: "pod",
507
- uid: pod.metadata.uid
508
- } }),
509
- pod.status?.phase ?? "Unknown",
510
- " ·",
511
- " ",
512
- pod.spec?.nodeName ? `Assigned to ${pod.spec.nodeName}` : "Unscheduled"
513
- ] }),
514
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: podSummary(pod, usage, "cpu") }),
515
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: podSummary(pod, usage, "memory") }),
516
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: pod.spec?.nodeName ? "—" : "Included above" })
517
- ] }, pod.metadata.uid))] });
518
- }
519
- function TrackButton({ identity }) {
520
- const preferences = require_monitoring_preferences_store.MonitoringPreferencesStore.getInstanceOrCreate();
521
- const [, update] = require__global_external_react.useState(0);
522
- require__global_external_react.useEffect(() => require__global_external_mobx.reaction(() => [preferences.historyEnabled, require_monitoring_history_collection.isHistoryTracked(identity)], () => update((value) => value + 1)), [
523
- identity.clusterId,
524
- identity.scope,
525
- identity.uid,
526
- preferences
527
- ]);
528
- const tracked = require_monitoring_history_collection.isHistoryTracked(identity);
529
- return /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
530
- type: "button",
531
- disabled: !preferences.historyEnabled,
532
- title: preferences.historyEnabled ? "Track numeric resource history locally" : "Enable local history in extension preferences",
533
- "aria-pressed": tracked,
534
- onClick: () => {
535
- if (activeId() !== identity.clusterId || !preferences.historyEnabled) return;
536
- require_monitoring_history_collection.setHistoryTracked(identity, !tracked);
537
- update((value) => value + 1);
538
- },
539
- children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: tracked ? "visibility" : "visibility_off" }), tracked ? "Stop tracking" : "Track history"]
540
- });
958
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
959
+ className: "numeric",
960
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(ResourceCell, {
961
+ summary: podResourceGroup(pod, usage).memory,
962
+ metric: "memory"
963
+ })
964
+ }),
965
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
966
+ className: "numeric",
967
+ children: /* @__PURE__ */ require_jsx_runtime.jsx("span", {
968
+ className: "unscheduled-empty",
969
+ title: pod.spec?.nodeName ? "No unscheduled requests" : "Unscheduled requests are included in the workload total",
970
+ children: pod.spec?.nodeName ? "—" : "Included above"
971
+ })
972
+ })
973
+ ]
974
+ }, pod.metadata.uid))] });
541
975
  }
542
976
  function podRequest(pod, metric) {
543
977
  try {
@@ -546,15 +980,7 @@ function podRequest(pod, metric) {
546
980
  return "Unavailable";
547
981
  }
548
982
  }
549
- function podSummary(pod, usage, metric) {
550
- let request;
551
- try {
552
- request = require_resource_diagnostics.effectivePodResource(pod, metric);
553
- } catch {}
554
- const value = usage.find((item) => item.uid === pod.metadata.uid)?.[metric];
555
- return `${resourceText(value, metric)}, requests ${resourceText(request, metric)}${value !== void 0 && request ? `, ${(value / request * 100).toFixed(0)}% of requests` : ", ratio unavailable"}`;
556
- }
557
- function NamespaceRows({ namespace, groups, clusterId, usage, open, toggleNamespace, expanded, toggleGroup, viewHistory }) {
983
+ function NamespaceRows({ namespace, groups, clusterId, usage, open, toggleNamespace, expanded, toggleGroup }) {
558
984
  const sum = (metric) => groups.reduce((total, group) => {
559
985
  const next = group[metric];
560
986
  return {
@@ -574,74 +1000,101 @@ function NamespaceRows({ namespace, groups, clusterId, usage, open, toggleNamesp
574
1000
  totalPods: 0,
575
1001
  unknownRequestPods: 0
576
1002
  });
577
- return /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [namespace && /* @__PURE__ */ require_jsx_runtime.jsxs("tr", { children: [
578
- /* @__PURE__ */ require_jsx_runtime.jsxs("td", { children: [/* @__PURE__ */ require_jsx_runtime.jsxs("button", {
579
- type: "button",
580
- title: "Expand namespace workloads",
581
- "aria-expanded": open,
582
- onClick: toggleNamespace,
583
- children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: open ? "expand_less" : "expand_more" }), namespace]
584
- }), /* @__PURE__ */ require_jsx_runtime.jsxs("small", { children: [groups.length, " consumers"] })] }),
585
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: summaryText(sum("cpu"), "cpu") }),
586
- /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: summaryText(sum("memory"), "memory") }),
587
- /* @__PURE__ */ require_jsx_runtime.jsxs("td", { children: [
588
- unscheduledText(sum("cpu"), "cpu"),
589
- " / ",
590
- unscheduledText(sum("memory"), "memory")
591
- ] })
592
- ] }), open && groups.map((group) => /* @__PURE__ */ require_jsx_runtime.jsx(ConsumerRows, {
1003
+ return /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [namespace && /* @__PURE__ */ require_jsx_runtime.jsxs("tr", {
1004
+ className: `consumer-namespace-row consumer-depth-0 consumer-tone-${consumerStatus(groups.flatMap((group) => group.pods)).tone}`,
1005
+ "data-row-depth": 0,
1006
+ children: [
1007
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", { children: /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
1008
+ className: "consumer-identity-row",
1009
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
1010
+ className: "consumer-identity-main",
1011
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
1012
+ className: "consumer-title-line",
1013
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("span", {
1014
+ className: "namespace-identity",
1015
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
1016
+ material: "folder_open",
1017
+ size: 17
1018
+ }), /* @__PURE__ */ require_jsx_runtime.jsx("span", {
1019
+ className: "consumer-identity-label",
1020
+ children: namespace
1021
+ })]
1022
+ }), /* @__PURE__ */ require_jsx_runtime.jsx(ConsumerStatus, { pods: groups.flatMap((group) => group.pods) })]
1023
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("small", {
1024
+ className: "consumer-subtitle",
1025
+ title: "Resource totals include only consumers shown by the current filters",
1026
+ children: [
1027
+ groups.length,
1028
+ " shown consumers",
1029
+ /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "·" }),
1030
+ groups.reduce((total, group) => total + group.pods.length, 0),
1031
+ " pods"
1032
+ ]
1033
+ })]
1034
+ }), /* @__PURE__ */ require_jsx_runtime.jsx("span", {
1035
+ className: "consumer-expand-slot",
1036
+ children: /* @__PURE__ */ require_jsx_runtime.jsx("button", {
1037
+ className: "consumer-expand",
1038
+ type: "button",
1039
+ title: open ? "Collapse namespace workloads" : "Expand namespace workloads",
1040
+ "aria-label": `${open ? "Collapse" : "Expand"} workloads in ${namespace}`,
1041
+ "aria-expanded": open,
1042
+ onClick: toggleNamespace,
1043
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: open ? "expand_less" : "expand_more" })
1044
+ })
1045
+ })]
1046
+ }) }),
1047
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
1048
+ className: "numeric",
1049
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(ResourceCell, {
1050
+ summary: sum("cpu"),
1051
+ metric: "cpu"
1052
+ })
1053
+ }),
1054
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
1055
+ className: "numeric",
1056
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(ResourceCell, {
1057
+ summary: sum("memory"),
1058
+ metric: "memory"
1059
+ })
1060
+ }),
1061
+ /* @__PURE__ */ require_jsx_runtime.jsx("td", {
1062
+ className: "numeric",
1063
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(UnscheduledCell, {
1064
+ cpu: sum("cpu"),
1065
+ memory: sum("memory")
1066
+ })
1067
+ })
1068
+ ]
1069
+ }), open && groups.map((group) => /* @__PURE__ */ require_jsx_runtime.jsx(ConsumerRows, {
593
1070
  group,
1071
+ depth: namespace ? 1 : 0,
594
1072
  clusterId,
595
1073
  expanded: expanded.includes(groupKey(group)),
596
1074
  toggle: () => toggleGroup(groupKey(group)),
597
- usage,
598
- viewHistory
1075
+ usage
599
1076
  }, groupKey(group)))] });
600
1077
  }
601
- function ApplicationHistory({ data, group }) {
602
- const live = require__global_external_react.useMemo(() => {
603
- if (!group || group.cpu.coveredPods !== group.cpu.totalPods || group.memory.coveredPods !== group.memory.totalPods || group.cpu.usage === void 0 || group.memory.usage === void 0) return [];
604
- const names = new Set(group.pods.map((pod) => `${pod.metadata.namespace}/${pod.metadata.name}`));
605
- const times = (data.podMetrics ?? []).filter((metric) => names.has(`${metric.metadata.namespace}/${metric.metadata.name}`)).map((metric) => Date.parse(metric.timestamp));
606
- if (!times.length || times.some((time) => !Number.isFinite(time))) return [];
607
- return [{
608
- time: Math.min(...times),
609
- cpu: group.cpu.usage,
610
- memory: group.memory.usage,
611
- resources: {
612
- cpu: { requests: group.cpu.unknownRequestPods ? void 0 : group.cpu.requests },
613
- memory: { requests: group.memory.unknownRequestPods ? void 0 : group.memory.requests }
614
- }
615
- }];
616
- }, [data, group]);
617
- const history = require_monitoring_history_view.useMonitoringHistory(group ? {
618
- clusterId: data.clusterId,
619
- scope: group.kind === "Pod" ? "pod" : "workload",
620
- uid: group.identity
621
- } : void 0, live);
622
- return /* @__PURE__ */ require_jsx_runtime.jsxs("section", {
623
- "aria-label": "Application resource history",
624
- children: [
625
- /* @__PURE__ */ require_jsx_runtime.jsxs("h3", { children: [group?.name ?? "Unavailable application", " resource history"] }),
626
- /* @__PURE__ */ require_jsx_runtime.jsx(require_monitoring_history_view.MonitoringHistoryRange, {
627
- range: history.range,
628
- onChange: history.setRange
629
- }),
630
- /* @__PURE__ */ require_jsx_runtime.jsx("p", {
631
- role: "status",
632
- children: history.status
633
- }),
634
- /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: live.length ? "Live usage includes every current pod; source metric timestamps are used" : "Complete current usage unavailable; missing coverage remains a gap" }),
635
- ["cpu", "memory"].map((metric) => /* @__PURE__ */ require_jsx_runtime.jsx(require_monitoring.MetricChart, {
636
- metric,
637
- samples: history.samples,
638
- scope: "pod",
639
- status: live.length ? "" : "Complete live usage unavailable"
640
- }, metric))
641
- ]
642
- });
1078
+ function podResourceGroup(pod, usage) {
1079
+ return require_resource_diagnostics.buildConsumerGroups([{
1080
+ ...pod,
1081
+ kind: "Pod",
1082
+ metadata: {
1083
+ ...pod.metadata,
1084
+ ownerReferences: []
1085
+ }
1086
+ }], [], usage)[0];
1087
+ }
1088
+ function eventCategory(reason) {
1089
+ if (reason === "Observed change") return "observed";
1090
+ if (reason === "Warning") return "warning";
1091
+ if (["Rollout", "RolloutObserved"].includes(reason)) return "rollout";
1092
+ if (reason === "Restart" || reason.startsWith("Restarts/")) return "restart";
1093
+ if (reason === "Readiness" || reason.startsWith("Readiness/")) return "readiness";
1094
+ return "event";
643
1095
  }
644
1096
  //#endregion
645
1097
  exports.DiagnosticsPage = DiagnosticsPage;
1098
+ exports.consumerStatus = consumerStatus;
646
1099
 
647
1100
  //# sourceMappingURL=diagnostics.js.map