@64mb/freelens-power 1.0.3 → 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 (224) hide show
  1. package/README.md +9 -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/monitoring-history.js +52 -0
  19. package/out/main/common/monitoring-history.js.map +1 -0
  20. package/out/main/common/settings-export.js +3 -1
  21. package/out/main/common/settings-export.js.map +1 -1
  22. package/out/main/common/store/cluster-icons-store.js +32 -0
  23. package/out/main/common/store/cluster-icons-store.js.map +1 -0
  24. package/out/main/common/store/monitoring-preferences-store.js +30 -2
  25. package/out/main/common/store/monitoring-preferences-store.js.map +1 -1
  26. package/out/main/dashboard-views.js +132 -28
  27. package/out/main/dashboard-views.js.map +1 -1
  28. package/out/main/diagnostics-menu-order.js +57 -0
  29. package/out/main/diagnostics-menu-order.js.map +1 -0
  30. package/out/main/index.js +11 -1
  31. package/out/main/index.js.map +1 -1
  32. package/out/main/monitoring-history-database.js +103 -0
  33. package/out/main/monitoring-history-database.js.map +1 -0
  34. package/out/main/monitoring-history-worker.js +61 -0
  35. package/out/main/monitoring-history-worker.js.map +1 -0
  36. package/out/main/monitoring-history.js +110 -0
  37. package/out/main/monitoring-history.js.map +1 -0
  38. package/out/renderer/_virtual/_global-external_mobx.js +2 -1
  39. package/out/renderer/_virtual/_global-external_react-dom.js +2 -1
  40. package/out/renderer/_virtual/_global-external_react.js +10 -5
  41. package/out/renderer/_virtual/_rolldown/runtime.js +22 -0
  42. package/out/renderer/ai-terminal-context.js +200 -0
  43. package/out/renderer/ai-terminal-context.js.map +1 -0
  44. package/out/renderer/ai.js +90 -9
  45. package/out/renderer/ai.js.map +1 -1
  46. package/out/renderer/appearance.js +1 -0
  47. package/out/renderer/appearance.js.map +1 -1
  48. package/out/renderer/cluster-icon-colors.js +188 -0
  49. package/out/renderer/cluster-icon-colors.js.map +1 -0
  50. package/out/renderer/cluster-icons.js +304 -0
  51. package/out/renderer/cluster-icons.js.map +1 -0
  52. package/out/renderer/dashboard.js +8 -5
  53. package/out/renderer/dashboard.js.map +1 -1
  54. package/out/renderer/details/secret-certificate-details.js +9 -2
  55. package/out/renderer/details/secret-certificate-details.js.map +1 -1
  56. package/out/renderer/diagnostics.css.js +39 -0
  57. package/out/renderer/diagnostics.css.js.map +1 -0
  58. package/out/renderer/diagnostics.js +1100 -0
  59. package/out/renderer/diagnostics.js.map +1 -0
  60. package/out/renderer/index.js +32 -0
  61. package/out/renderer/index.js.map +1 -1
  62. package/out/renderer/monitoring-collector.js +202 -0
  63. package/out/renderer/monitoring-collector.js.map +1 -0
  64. package/out/renderer/monitoring-details-chart.js +42 -0
  65. package/out/renderer/monitoring-details-chart.js.map +1 -0
  66. package/out/renderer/monitoring-history-collection.js +168 -0
  67. package/out/renderer/monitoring-history-collection.js.map +1 -0
  68. package/out/renderer/monitoring-history-view.js +227 -0
  69. package/out/renderer/monitoring-history-view.js.map +1 -0
  70. package/out/renderer/monitoring-history.js +19 -0
  71. package/out/renderer/monitoring-history.js.map +1 -0
  72. package/out/renderer/monitoring.js +153 -139
  73. package/out/renderer/monitoring.js.map +1 -1
  74. package/out/renderer/node-monitoring.js +127 -0
  75. package/out/renderer/node-monitoring.js.map +1 -0
  76. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js +10 -0
  77. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js.map +1 -0
  78. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js +8 -0
  79. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js.map +1 -0
  80. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js +9 -0
  81. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js.map +1 -0
  82. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js +9 -0
  83. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js.map +1 -0
  84. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/classCallCheck.js +8 -0
  85. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/classCallCheck.js.map +1 -0
  86. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createClass.js +15 -0
  87. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createClass.js.map +1 -0
  88. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createSuper.js +19 -0
  89. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createSuper.js.map +1 -0
  90. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/defineProperty.js +14 -0
  91. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/defineProperty.js.map +1 -0
  92. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js +19 -0
  93. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js.map +1 -0
  94. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js +15 -0
  95. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js.map +1 -0
  96. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inherits.js +14 -0
  97. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inherits.js.map +1 -0
  98. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js +18 -0
  99. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js.map +1 -0
  100. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArray.js +8 -0
  101. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArray.js.map +1 -0
  102. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js +26 -0
  103. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js.map +1 -0
  104. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js +8 -0
  105. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js.map +1 -0
  106. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js +8 -0
  107. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js.map +1 -0
  108. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectSpread2.js +27 -0
  109. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectSpread2.js.map +1 -0
  110. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js +15 -0
  111. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js.map +1 -0
  112. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +14 -0
  113. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js.map +1 -0
  114. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js +12 -0
  115. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js.map +1 -0
  116. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js +15 -0
  117. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js.map +1 -0
  118. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/slicedToArray.js +12 -0
  119. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/slicedToArray.js.map +1 -0
  120. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js +8 -0
  121. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js.map +1 -0
  122. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js +12 -0
  123. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js.map +1 -0
  124. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPrimitive.js +16 -0
  125. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPrimitive.js.map +1 -0
  126. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js +11 -0
  127. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js.map +1 -0
  128. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/typeof.js +18 -0
  129. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/typeof.js.map +1 -0
  130. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js +13 -0
  131. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js.map +1 -0
  132. package/out/renderer/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js +237 -0
  133. package/out/renderer/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js.map +1 -0
  134. package/out/renderer/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js +25 -0
  135. package/out/renderer/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js.map +1 -0
  136. package/out/renderer/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js +12 -0
  137. package/out/renderer/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js.map +1 -0
  138. 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
  139. 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
  140. 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
  141. 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
  142. package/out/renderer/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js +133 -0
  143. package/out/renderer/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js.map +1 -0
  144. package/out/renderer/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js +65 -0
  145. package/out/renderer/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js.map +1 -0
  146. package/out/renderer/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js +54 -0
  147. package/out/renderer/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js.map +1 -0
  148. 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
  149. 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
  150. package/out/renderer/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js +30 -0
  151. package/out/renderer/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js.map +1 -0
  152. package/out/renderer/node_modules/.pnpm/@floating-ui_dom@1.7.2/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +211 -0
  153. 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
  154. 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
  155. 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
  156. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +31 -0
  157. 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
  158. 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
  159. 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
  160. package/out/renderer/node_modules/.pnpm/memoize-one@6.0.0/node_modules/memoize-one/dist/memoize-one.esm.js +38 -0
  161. package/out/renderer/node_modules/.pnpm/memoize-one@6.0.0/node_modules/memoize-one/dist/memoize-one.esm.js.map +1 -0
  162. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js +159 -0
  163. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js.map +1 -0
  164. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js +103 -0
  165. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
  166. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js +18 -0
  167. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js.map +1 -0
  168. 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
  169. 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
  170. 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
  171. 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
  172. 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
  173. 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
  174. 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
  175. 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
  176. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js +22 -0
  177. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js.map +1 -0
  178. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js +30 -0
  179. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js.map +1 -0
  180. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js +164 -0
  181. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js.map +1 -0
  182. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js +37 -0
  183. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js.map +1 -0
  184. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js +245 -0
  185. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js.map +1 -0
  186. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js +120 -0
  187. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js.map +1 -0
  188. 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
  189. 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
  190. package/out/renderer/pod-monitoring.js +38 -11
  191. package/out/renderer/pod-monitoring.js.map +1 -1
  192. package/out/renderer/preferences/ai-shortcuts-preferences.js +12 -4
  193. package/out/renderer/preferences/ai-shortcuts-preferences.js.map +1 -1
  194. package/out/renderer/preferences/dashboard-preferences.js +20 -4
  195. package/out/renderer/preferences/dashboard-preferences.js.map +1 -1
  196. package/out/renderer/preferences/monitoring-preferences.js +141 -9
  197. package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
  198. package/out/renderer/preferences/preferences.js +31 -7
  199. package/out/renderer/preferences/preferences.js.map +1 -1
  200. package/out/renderer/read-only.js +2 -2
  201. package/out/renderer/read-only.js.map +1 -1
  202. package/out/renderer/src/common/ai-terminal-context.js +51 -0
  203. package/out/renderer/src/common/ai-terminal-context.js.map +1 -0
  204. package/out/renderer/src/common/ai.js.map +1 -1
  205. package/out/renderer/src/common/cluster-icon-ipc.js +6 -0
  206. package/out/renderer/src/common/cluster-icon-ipc.js.map +1 -0
  207. package/out/renderer/src/common/cluster-icons.js +133 -0
  208. package/out/renderer/src/common/cluster-icons.js.map +1 -0
  209. package/out/renderer/src/common/dashboard.js +1 -1
  210. package/out/renderer/src/common/dashboard.js.map +1 -1
  211. package/out/renderer/src/common/date-time.js +11 -0
  212. package/out/renderer/src/common/date-time.js.map +1 -0
  213. package/out/renderer/src/common/monitoring-history.js +17 -0
  214. package/out/renderer/src/common/monitoring-history.js.map +1 -0
  215. package/out/renderer/src/common/monitoring-math.js +98 -0
  216. package/out/renderer/src/common/monitoring-math.js.map +1 -0
  217. package/out/renderer/src/common/resource-diagnostics.js +227 -0
  218. package/out/renderer/src/common/resource-diagnostics.js.map +1 -0
  219. package/out/renderer/src/common/settings-export.js.map +1 -1
  220. package/out/renderer/src/common/store/monitoring-preferences-store.js +30 -2
  221. package/out/renderer/src/common/store/monitoring-preferences-store.js.map +1 -1
  222. package/out/renderer/welcome.js +31 -7
  223. package/out/renderer/welcome.js.map +1 -1
  224. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"preferences.js","names":[],"sources":["../../../src/renderer/preferences/preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { AiPreferences } from \"./ai-preferences\";\nimport { AppearancePreferences } from \"./appearance-preferences\";\nimport { DashboardPreferences } from \"./dashboard-preferences\";\nimport { MonitoringPreferences } from \"./monitoring-preferences\";\nimport { NodeShellPreferences } from \"./node-shell-preferences\";\nimport { PowerPreferencesToggle } from \"./power-preferences\";\nimport { ReadOnlyPreferences } from \"./read-only-preferences\";\nimport { SettingsExport } from \"./settings-export\";\n\nconst styles = `\n .power-preferences-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; }\n .power-preferences-header-actions { display: inline-flex; margin-left: auto; flex-shrink: 0; }\n #freelens-power-settings > .SubTitle,\n #freelens-power-settings > .hint,\n #freelens-power-settings + hr { display: none; }\n .freelens-power-preferences { display: grid; gap: 24px; max-width: 760px; }\n .freelens-power-preferences section {\n padding: 24px; border: 1px solid var(--borderFaintColor);\n border-radius: 12px; background: var(--contentColor);\n }\n .freelens-power-preferences button, .freelens-power-preferences .Button { transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease; }\n :root .freelens-power-preferences button.power-settings-icon-action,\n :root .power-preferences-header-actions button.power-settings-icon-action {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; min-width: 32px; padding: 0; flex-shrink: 0;\n border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); cursor: pointer;\n transition: color 160ms ease, background-color 160ms ease;\n }\n :root .freelens-power-preferences button.power-settings-icon-action:not(:disabled):hover,\n :root .power-preferences-header-actions button.power-settings-icon-action:not(:disabled):hover {\n color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent);\n }\n :root .freelens-power-preferences button.power-settings-icon-action:focus-visible,\n :root .power-preferences-header-actions button.power-settings-icon-action:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n :root .freelens-power-preferences button.power-settings-icon-action:disabled,\n :root .power-preferences-header-actions button.power-settings-icon-action:disabled { opacity: 0.4; cursor: default; }\n .freelens-power-preferences h3 {\n display: flex; align-items: center; gap: 10px; margin: 0 0 24px; font-size: 16px; font-weight: 600; color: var(--textColorAccent);\n }\n .freelens-power-preferences label[data-testid=\"switch\"] {\n display: flex; width: 100%; align-items: center; justify-content: space-between;\n }\n .freelens-power-preferences .power-settings-hint {\n margin-top: 6px; font-size: 12px; line-height: 1.5; color: var(--textColorSecondary);\n }\n @media (max-width: 760px) {\n .freelens-power-preferences section { padding: 18px; }\n .freelens-power-preferences .power-settings-row { flex-wrap: wrap; }\n }\n`;\n\nexport const PowerPreferences = () => (\n <div className=\"freelens-power-preferences\">\n <style>{styles}</style>\n <SettingsExport />\n <section aria-label=\"Freelens Power\">\n <PowerPreferencesToggle />\n </section>\n <section aria-labelledby=\"freelens-power-safety-title\">\n <h3 id=\"freelens-power-safety-title\">\n <Renderer.Component.Icon material=\"lock_outline\" size={20} /> Read-only mode\n </h3>\n <ReadOnlyPreferences />\n </section>\n <section aria-labelledby=\"freelens-power-appearance-title\">\n <h3 id=\"freelens-power-appearance-title\">\n <Renderer.Component.Icon material=\"palette\" size={20} /> Appearance\n </h3>\n <AppearancePreferences />\n </section>\n <section aria-labelledby=\"freelens-power-monitoring-title\">\n <h3 id=\"freelens-power-monitoring-title\">\n <Renderer.Component.Icon material=\"show_chart\" size={20} /> Monitoring\n </h3>\n <MonitoringPreferences />\n </section>\n <section aria-labelledby=\"freelens-power-shell-title\">\n <h3 id=\"freelens-power-shell-title\">\n <Renderer.Component.Icon material=\"vpn_key\" size={20} /> Secure Node Shell\n </h3>\n <NodeShellPreferences />\n </section>\n <section aria-labelledby=\"freelens-power-ai-title\">\n <h3 id=\"freelens-power-ai-title\">\n <Renderer.Component.Icon material=\"chat_bubble_outline\" size={20} /> AI assistant\n </h3>\n <AiPreferences />\n </section>\n <section aria-labelledby=\"freelens-power-dashboard-title\">\n <h3 id=\"freelens-power-dashboard-title\">\n <Renderer.Component.Icon material=\"dashboard\" size={20} /> Dashboard\n </h3>\n <DashboardPreferences />\n </section>\n </div>\n);\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0Cf,IAAa,yBACX,oCAAA,KAAC,OAAD;CAAK,WAAU;WAAf;EACE,oCAAA,IAAC,SAAD,EAAA,UAAQ,OAAc,CAAA;EACtB,oCAAA,IAAC,wBAAA,gBAAD,CAAiB,CAAA;EACjB,oCAAA,IAAC,WAAD;GAAS,cAAW;aAClB,oCAAA,IAAC,0BAAA,wBAAD,CAAyB,CAAA;EAClB,CAAA;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAe,MAAM;IAAK,CAAA,GAAC,iBAC3D;OACJ,oCAAA,IAAC,8BAAA,qBAAD,CAAsB,CAAA,CACf;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAU,MAAM;IAAK,CAAA,GAAC,aACtD;OACJ,oCAAA,IAAC,+BAAA,uBAAD,CAAwB,CAAA,CACjB;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAa,MAAM;IAAK,CAAA,GAAC,aACzD;OACJ,oCAAA,IAAC,+BAAA,uBAAD,CAAwB,CAAA,CACjB;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAU,MAAM;IAAK,CAAA,GAAC,oBACtD;OACJ,oCAAA,IAAC,+BAAA,sBAAD,CAAuB,CAAA,CAChB;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAsB,MAAM;IAAK,CAAA,GAAC,eAClE;OACJ,oCAAA,IAAC,uBAAA,eAAD,CAAgB,CAAA,CACT;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAY,MAAM;IAAK,CAAA,GAAC,YACxD;OACJ,oCAAA,IAAC,8BAAA,sBAAD,CAAuB,CAAA,CAChB;;CACN"}
1
+ {"version":3,"file":"preferences.js","names":[],"sources":["../../../src/renderer/preferences/preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { EXTENSION_ID } from \"../../common/extension-info\";\nimport { AiPreferences } from \"./ai-preferences\";\nimport { AppearancePreferences } from \"./appearance-preferences\";\nimport { DashboardPreferences } from \"./dashboard-preferences\";\nimport { MonitoringPreferences } from \"./monitoring-preferences\";\nimport { NodeShellPreferences } from \"./node-shell-preferences\";\nimport { PowerPreferencesToggle } from \"./power-preferences\";\nimport { ReadOnlyPreferences } from \"./read-only-preferences\";\nimport { SettingsExport } from \"./settings-export\";\n\nconst styles = `\n .power-preferences-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; }\n .power-preferences-header-actions { display: inline-flex; margin-left: auto; flex-shrink: 0; }\n #freelens-power-settings > .SubTitle,\n #freelens-power-settings > .hint,\n #freelens-power-settings + hr { display: none; }\n .freelens-power-preferences { display: grid; gap: 24px; max-width: 760px; }\n .freelens-power-preferences section {\n padding: 24px; border: 1px solid var(--borderFaintColor);\n border-radius: 12px; background: var(--contentColor);\n }\n .freelens-power-preferences button, .freelens-power-preferences .Button { transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease; }\n :root .freelens-power-preferences button.power-settings-icon-action,\n :root .power-preferences-header-actions button.power-settings-icon-action {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; min-width: 32px; padding: 0; flex-shrink: 0;\n border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); cursor: pointer;\n transition: color 160ms ease, background-color 160ms ease;\n }\n :root .freelens-power-preferences button.power-settings-icon-action:not(:disabled):hover,\n :root .power-preferences-header-actions button.power-settings-icon-action:not(:disabled):hover {\n color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent);\n }\n :root .freelens-power-preferences button.power-settings-icon-action:focus-visible,\n :root .power-preferences-header-actions button.power-settings-icon-action:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n :root .freelens-power-preferences button.power-settings-icon-action:disabled,\n :root .power-preferences-header-actions button.power-settings-icon-action:disabled { opacity: 0.4; cursor: default; }\n .freelens-power-preferences h3 {\n display: flex; align-items: center; gap: 10px; margin: 0 0 24px; font-size: 16px; font-weight: 600; color: var(--textColorAccent);\n }\n .freelens-power-preferences label[data-testid=\"switch\"] {\n display: flex; width: 100%; align-items: center; justify-content: space-between;\n }\n .freelens-power-preferences .power-settings-hint {\n margin-top: 6px; font-size: 12px; line-height: 1.5; color: var(--textColorSecondary);\n }\n @media (max-width: 760px) {\n .freelens-power-preferences section { padding: 18px; }\n .freelens-power-preferences .power-settings-row { flex-wrap: wrap; }\n }\n`;\n\nexport const PowerPreferences = () => (\n <div className=\"freelens-power-preferences\">\n <style>{styles}</style>\n <SettingsExport />\n <section aria-label=\"Freelens Power\">\n <PowerPreferencesToggle />\n </section>\n <section aria-labelledby=\"freelens-power-safety-title\">\n <h3 id=\"freelens-power-safety-title\">\n <Renderer.Component.Icon material=\"lock_outline\" size={20} /> Read-only mode\n </h3>\n <ReadOnlyPreferences />\n </section>\n <section aria-labelledby=\"freelens-power-appearance-title\">\n <h3 id=\"freelens-power-appearance-title\">\n <Renderer.Component.Icon material=\"palette\" size={20} /> Appearance\n </h3>\n <AppearancePreferences />\n <div style={{ display: \"flex\", justifyContent: \"flex-end\", marginTop: 20 }}>\n <Renderer.Component.Button\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n onClick={() => Renderer.Navigation.navigate(`/extension/${EXTENSION_ID}/cluster-icons`)}\n title=\"Create matching icons for your saved clusters\"\n >\n <Renderer.Component.Icon material=\"palette\" size={16} /> Cluster icons\n </Renderer.Component.Button>\n </div>\n </section>\n <section aria-labelledby=\"freelens-power-monitoring-title\">\n <h3 id=\"freelens-power-monitoring-title\">\n <Renderer.Component.Icon material=\"show_chart\" size={20} /> Monitoring\n </h3>\n <MonitoringPreferences />\n </section>\n <section aria-labelledby=\"freelens-power-shell-title\">\n <h3 id=\"freelens-power-shell-title\">\n <Renderer.Component.Icon material=\"vpn_key\" size={20} /> Secure Node Shell\n </h3>\n <NodeShellPreferences />\n </section>\n <section aria-labelledby=\"freelens-power-ai-title\">\n <h3 id=\"freelens-power-ai-title\">\n <Renderer.Component.Icon material=\"chat_bubble_outline\" size={20} /> AI assistant\n </h3>\n <AiPreferences />\n </section>\n <section aria-labelledby=\"freelens-power-dashboard-title\">\n <h3 id=\"freelens-power-dashboard-title\">\n <Renderer.Component.Icon material=\"dashboard\" size={20} /> Dashboard\n </h3>\n <DashboardPreferences />\n </section>\n </div>\n);\n"],"mappings":";;;;;;;;;;;;AAWA,IAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0Cf,IAAa,yBACX,oCAAA,KAAC,OAAD;CAAK,WAAU;WAAf;EACE,oCAAA,IAAC,SAAD,EAAA,UAAQ,OAAc,CAAA;EACtB,oCAAA,IAAC,wBAAA,gBAAD,CAAiB,CAAA;EACjB,oCAAA,IAAC,WAAD;GAAS,cAAW;aAClB,oCAAA,IAAC,0BAAA,wBAAD,CAAyB,CAAA;EAClB,CAAA;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAe,MAAM;IAAK,CAAA,GAAC,iBAC3D;OACJ,oCAAA,IAAC,8BAAA,qBAAD,CAAsB,CAAA,CACf;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB;IACE,oCAAA,KAAC,MAAD;KAAI,IAAG;eAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;MAAyB,UAAS;MAAU,MAAM;KAAK,CAAA,GAAC,aACtD;;IACJ,oCAAA,IAAC,+BAAA,uBAAD,CAAwB,CAAA;IACxB,oCAAA,IAAC,OAAD;KAAK,OAAO;MAAE,SAAS;MAAQ,gBAAgB;MAAY,WAAW;KAAG;eACvE,oCAAA,KAAC,mBAAA,SAAS,UAAU,QAApB;MACE,OAAO;OAAE,SAAS;OAAe,YAAY;OAAU,KAAK;MAAE;MAC9D,eAAe,mBAAA,SAAS,WAAW,SAAS,cAAc,uBAAA,aAAa,eAAe;MACtF,OAAM;gBAHR,CAKE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;OAAyB,UAAS;OAAU,MAAM;MAAK,CAAA,GAAC,gBAC/B;;IACxB,CAAA;GACE;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAa,MAAM;IAAK,CAAA,GAAC,aACzD;OACJ,oCAAA,IAAC,+BAAA,uBAAD,CAAwB,CAAA,CACjB;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAU,MAAM;IAAK,CAAA,GAAC,oBACtD;OACJ,oCAAA,IAAC,+BAAA,sBAAD,CAAuB,CAAA,CAChB;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAsB,MAAM;IAAK,CAAA,GAAC,eAClE;OACJ,oCAAA,IAAC,uBAAA,eAAD,CAAgB,CAAA,CACT;;EACT,oCAAA,KAAC,WAAD;GAAS,mBAAgB;aAAzB,CACE,oCAAA,KAAC,MAAD;IAAI,IAAG;cAAP,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;KAAyB,UAAS;KAAY,MAAM;IAAK,CAAA,GAAC,YACxD;OACJ,oCAAA,IAAC,8BAAA,sBAAD,CAAuB,CAAA,CAChB;;CACN"}
@@ -6,7 +6,7 @@ var excluded = ".freelens-power-preferences, #freelens-power-settings, .freelens
6
6
  var directActions = [
7
7
  ".CatalogAddButton",
8
8
  ".KubeObjectListLayout .AddRemoveButtons .add-button",
9
- ".KubeObjectListLayout .AddRemoveButtons .remove-button",
9
+ ".AddRemoveButtons .remove-button",
10
10
  ".create-resource-tab",
11
11
  ".CreateResource .InfoPanel button.active",
12
12
  "[data-testid^=\"save-edit-resource-from-tab-for-\"]",
@@ -35,7 +35,7 @@ function startReadOnlyMode() {
35
35
  const preferences = require_read_only_preferences_store.ReadOnlyPreferencesStore.getInstanceOrCreate();
36
36
  const style = document.createElement("style");
37
37
  style.dataset.freelensPower = "read-only";
38
- style.textContent = `[${marker}] { display: none !important; }`;
38
+ style.textContent = `[${marker}], .AddRemoveButtons .remove-button { display: none !important; }`;
39
39
  const hidden = /* @__PURE__ */ new Set();
40
40
  function restore() {
41
41
  for (const element of hidden) element.removeAttribute(marker);
@@ -1 +1 @@
1
- {"version":3,"file":"read-only.js","names":[],"sources":["../../src/renderer/read-only.ts"],"sourcesContent":["import { reaction } from \"mobx\";\nimport { ReadOnlyPreferencesStore } from \"../common/store/read-only-preferences-store\";\n\nconst marker = \"data-freelens-power-read-only\";\nconst excluded = \".freelens-power-preferences, #freelens-power-settings, .freelens-power-dashboard, .power-ai-panel\";\nconst directActions = [\n \".CatalogAddButton\",\n \".KubeObjectListLayout .AddRemoveButtons .add-button\",\n \".KubeObjectListLayout .AddRemoveButtons .remove-button\",\n \".create-resource-tab\",\n \".CreateResource .InfoPanel button.active\",\n '[data-testid^=\"save-edit-resource-from-tab-for-\"]',\n '[data-testid^=\"save-and-close-edit-resource-from-tab-for-\"]',\n '[data-testid^=\"menu-action-edit-for-\"]',\n '[data-testid^=\"menu-action-delete-for-\"]',\n '[data-testid^=\"menu-action-force-delete-for-\"]',\n '[data-testid^=\"menu-action-delete-with-finalizers-for-\"]',\n '.MenuActions [data-testid=\"menu-action-remove\"]',\n].join(\",\");\nconst menuActions = new Set([\n \"edit\",\n \"delete\",\n \"force delete\",\n \"delete with finalizers\",\n \"remove\",\n \"remove cluster\",\n \"delete cluster\",\n \"cordon\",\n \"uncordon\",\n \"drain\",\n \"scale\",\n \"restart\",\n]);\n\nexport function startReadOnlyMode(): () => void {\n const preferences = ReadOnlyPreferencesStore.getInstanceOrCreate<ReadOnlyPreferencesStore>();\n const style = document.createElement(\"style\");\n style.dataset.freelensPower = \"read-only\";\n style.textContent = `[${marker}] { display: none !important; }`;\n const hidden = new Set<HTMLElement>();\n\n function restore() {\n for (const element of hidden) element.removeAttribute(marker);\n hidden.clear();\n style.remove();\n }\n\n function isMutation(element: HTMLElement): boolean {\n if (element.closest(excluded)) return false;\n if (element.matches(directActions)) return true;\n if (!element.matches('.MenuActions .MenuItem, [data-testid^=\"menu-actions-for-kube-object-menu-\"] .MenuItem'))\n return false;\n const title = (element.querySelector(\".title\")?.textContent ?? element.textContent)?.trim().toLowerCase();\n if (title && menuActions.has(title)) return true;\n return !!element.querySelector(\n '[data-icon-name=\"edit\"], [data-icon-name=\"delete\"], [data-icon-name=\"delete_forever\"], [data-icon-name=\"delete_sweep\"], [data-icon-name=\"pause_circle_filled\"], [data-icon-name=\"play_circle_filled\"]',\n );\n }\n\n function refresh() {\n for (const element of hidden) {\n if (!element.isConnected || !isMutation(element)) {\n element.removeAttribute(marker);\n hidden.delete(element);\n }\n }\n for (const element of document.querySelectorAll<HTMLElement>(`${directActions}, .MenuActions .MenuItem`)) {\n if (isMutation(element)) {\n element.setAttribute(marker, \"\");\n hidden.add(element);\n }\n }\n }\n\n function intercept(event: Event) {\n if (!preferences.enabled || !(event.target instanceof Element)) return;\n if (event instanceof KeyboardEvent && ![\"Enter\", \" \"].includes(event.key)) return;\n const target = event.target.closest<HTMLElement>(`[${marker}], ${directActions}, .MenuItem`);\n if (!target || !isMutation(target)) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n\n const observer = new MutationObserver(refresh);\n const stop = reaction(\n () => preferences.enabled,\n (enabled) => {\n observer.disconnect();\n restore();\n if (!enabled) return;\n document.head.append(style);\n refresh();\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: [\"class\", \"data-testid\", \"title\"],\n });\n },\n { fireImmediately: true },\n );\n document.addEventListener(\"click\", intercept, true);\n document.addEventListener(\"keydown\", intercept, true);\n\n return () => {\n stop();\n observer.disconnect();\n document.removeEventListener(\"click\", intercept, true);\n document.removeEventListener(\"keydown\", intercept, true);\n restore();\n };\n}\n"],"mappings":";;;AAGA,IAAM,SAAS;AACf,IAAM,WAAW;AACjB,IAAM,gBAAgB;CACpB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;AACV,IAAM,8BAAc,IAAI,IAAI;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAgB,oBAAgC;CAC9C,MAAM,cAAc,oCAAA,yBAAyB,oBAA8C;CAC3F,MAAM,QAAQ,SAAS,cAAc,OAAO;CAC5C,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,cAAc,IAAI,OAAO;CAC/B,MAAM,yBAAS,IAAI,IAAiB;CAEpC,SAAS,UAAU;EACjB,KAAK,MAAM,WAAW,QAAQ,QAAQ,gBAAgB,MAAM;EAC5D,OAAO,MAAM;EACb,MAAM,OAAO;CACf;CAEA,SAAS,WAAW,SAA+B;EACjD,IAAI,QAAQ,QAAQ,QAAQ,GAAG,OAAO;EACtC,IAAI,QAAQ,QAAQ,aAAa,GAAG,OAAO;EAC3C,IAAI,CAAC,QAAQ,QAAQ,yFAAuF,GAC1G,OAAO;EACT,MAAM,SAAS,QAAQ,cAAc,QAAQ,CAAC,EAAE,eAAe,QAAQ,YAAA,EAAc,KAAK,CAAC,CAAC,YAAY;EACxG,IAAI,SAAS,YAAY,IAAI,KAAK,GAAG,OAAO;EAC5C,OAAO,CAAC,CAAC,QAAQ,cACf,mNACF;CACF;CAEA,SAAS,UAAU;EACjB,KAAK,MAAM,WAAW,QACpB,IAAI,CAAC,QAAQ,eAAe,CAAC,WAAW,OAAO,GAAG;GAChD,QAAQ,gBAAgB,MAAM;GAC9B,OAAO,OAAO,OAAO;EACvB;EAEF,KAAK,MAAM,WAAW,SAAS,iBAA8B,GAAG,cAAc,yBAAyB,GACrG,IAAI,WAAW,OAAO,GAAG;GACvB,QAAQ,aAAa,QAAQ,EAAE;GAC/B,OAAO,IAAI,OAAO;EACpB;CAEJ;CAEA,SAAS,UAAU,OAAc;EAC/B,IAAI,CAAC,YAAY,WAAW,EAAE,MAAM,kBAAkB,UAAU;EAChE,IAAI,iBAAiB,iBAAiB,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG;EAC3E,MAAM,SAAS,MAAM,OAAO,QAAqB,IAAI,OAAO,KAAK,cAAc,YAAY;EAC3F,IAAI,CAAC,UAAU,CAAC,WAAW,MAAM,GAAG;EACpC,MAAM,eAAe;EACrB,MAAM,yBAAyB;CACjC;CAEA,MAAM,WAAW,IAAI,iBAAiB,OAAO;CAC7C,MAAM,OAAO,8BAAA,eACL,YAAY,UACjB,YAAY;EACX,SAAS,WAAW;EACpB,QAAQ;EACR,IAAI,CAAC,SAAS;EACd,SAAS,KAAK,OAAO,KAAK;EAC1B,QAAQ;EACR,SAAS,QAAQ,SAAS,MAAM;GAC9B,WAAW;GACX,SAAS;GACT,eAAe;GACf,YAAY;GACZ,iBAAiB;IAAC;IAAS;IAAe;GAAO;EACnD,CAAC;CACH,GACA,EAAE,iBAAiB,KAAK,CAC1B;CACA,SAAS,iBAAiB,SAAS,WAAW,IAAI;CAClD,SAAS,iBAAiB,WAAW,WAAW,IAAI;CAEpD,aAAa;EACX,KAAK;EACL,SAAS,WAAW;EACpB,SAAS,oBAAoB,SAAS,WAAW,IAAI;EACrD,SAAS,oBAAoB,WAAW,WAAW,IAAI;EACvD,QAAQ;CACV;AACF"}
1
+ {"version":3,"file":"read-only.js","names":[],"sources":["../../src/renderer/read-only.ts"],"sourcesContent":["import { reaction } from \"mobx\";\nimport { ReadOnlyPreferencesStore } from \"../common/store/read-only-preferences-store\";\n\nconst marker = \"data-freelens-power-read-only\";\nconst excluded = \".freelens-power-preferences, #freelens-power-settings, .freelens-power-dashboard, .power-ai-panel\";\nconst directActions = [\n \".CatalogAddButton\",\n \".KubeObjectListLayout .AddRemoveButtons .add-button\",\n \".AddRemoveButtons .remove-button\",\n \".create-resource-tab\",\n \".CreateResource .InfoPanel button.active\",\n '[data-testid^=\"save-edit-resource-from-tab-for-\"]',\n '[data-testid^=\"save-and-close-edit-resource-from-tab-for-\"]',\n '[data-testid^=\"menu-action-edit-for-\"]',\n '[data-testid^=\"menu-action-delete-for-\"]',\n '[data-testid^=\"menu-action-force-delete-for-\"]',\n '[data-testid^=\"menu-action-delete-with-finalizers-for-\"]',\n '.MenuActions [data-testid=\"menu-action-remove\"]',\n].join(\",\");\nconst menuActions = new Set([\n \"edit\",\n \"delete\",\n \"force delete\",\n \"delete with finalizers\",\n \"remove\",\n \"remove cluster\",\n \"delete cluster\",\n \"cordon\",\n \"uncordon\",\n \"drain\",\n \"scale\",\n \"restart\",\n]);\n\nexport function startReadOnlyMode(): () => void {\n const preferences = ReadOnlyPreferencesStore.getInstanceOrCreate<ReadOnlyPreferencesStore>();\n const style = document.createElement(\"style\");\n style.dataset.freelensPower = \"read-only\";\n style.textContent = `[${marker}], .AddRemoveButtons .remove-button { display: none !important; }`;\n const hidden = new Set<HTMLElement>();\n\n function restore() {\n for (const element of hidden) element.removeAttribute(marker);\n hidden.clear();\n style.remove();\n }\n\n function isMutation(element: HTMLElement): boolean {\n if (element.closest(excluded)) return false;\n if (element.matches(directActions)) return true;\n if (!element.matches('.MenuActions .MenuItem, [data-testid^=\"menu-actions-for-kube-object-menu-\"] .MenuItem'))\n return false;\n const title = (element.querySelector(\".title\")?.textContent ?? element.textContent)?.trim().toLowerCase();\n if (title && menuActions.has(title)) return true;\n return !!element.querySelector(\n '[data-icon-name=\"edit\"], [data-icon-name=\"delete\"], [data-icon-name=\"delete_forever\"], [data-icon-name=\"delete_sweep\"], [data-icon-name=\"pause_circle_filled\"], [data-icon-name=\"play_circle_filled\"]',\n );\n }\n\n function refresh() {\n for (const element of hidden) {\n if (!element.isConnected || !isMutation(element)) {\n element.removeAttribute(marker);\n hidden.delete(element);\n }\n }\n for (const element of document.querySelectorAll<HTMLElement>(`${directActions}, .MenuActions .MenuItem`)) {\n if (isMutation(element)) {\n element.setAttribute(marker, \"\");\n hidden.add(element);\n }\n }\n }\n\n function intercept(event: Event) {\n if (!preferences.enabled || !(event.target instanceof Element)) return;\n if (event instanceof KeyboardEvent && ![\"Enter\", \" \"].includes(event.key)) return;\n const target = event.target.closest<HTMLElement>(`[${marker}], ${directActions}, .MenuItem`);\n if (!target || !isMutation(target)) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n\n const observer = new MutationObserver(refresh);\n const stop = reaction(\n () => preferences.enabled,\n (enabled) => {\n observer.disconnect();\n restore();\n if (!enabled) return;\n document.head.append(style);\n refresh();\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: [\"class\", \"data-testid\", \"title\"],\n });\n },\n { fireImmediately: true },\n );\n document.addEventListener(\"click\", intercept, true);\n document.addEventListener(\"keydown\", intercept, true);\n\n return () => {\n stop();\n observer.disconnect();\n document.removeEventListener(\"click\", intercept, true);\n document.removeEventListener(\"keydown\", intercept, true);\n restore();\n };\n}\n"],"mappings":";;;AAGA,IAAM,SAAS;AACf,IAAM,WAAW;AACjB,IAAM,gBAAgB;CACpB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;AACV,IAAM,8BAAc,IAAI,IAAI;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAgB,oBAAgC;CAC9C,MAAM,cAAc,oCAAA,yBAAyB,oBAA8C;CAC3F,MAAM,QAAQ,SAAS,cAAc,OAAO;CAC5C,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,cAAc,IAAI,OAAO;CAC/B,MAAM,yBAAS,IAAI,IAAiB;CAEpC,SAAS,UAAU;EACjB,KAAK,MAAM,WAAW,QAAQ,QAAQ,gBAAgB,MAAM;EAC5D,OAAO,MAAM;EACb,MAAM,OAAO;CACf;CAEA,SAAS,WAAW,SAA+B;EACjD,IAAI,QAAQ,QAAQ,QAAQ,GAAG,OAAO;EACtC,IAAI,QAAQ,QAAQ,aAAa,GAAG,OAAO;EAC3C,IAAI,CAAC,QAAQ,QAAQ,yFAAuF,GAC1G,OAAO;EACT,MAAM,SAAS,QAAQ,cAAc,QAAQ,CAAC,EAAE,eAAe,QAAQ,YAAA,EAAc,KAAK,CAAC,CAAC,YAAY;EACxG,IAAI,SAAS,YAAY,IAAI,KAAK,GAAG,OAAO;EAC5C,OAAO,CAAC,CAAC,QAAQ,cACf,mNACF;CACF;CAEA,SAAS,UAAU;EACjB,KAAK,MAAM,WAAW,QACpB,IAAI,CAAC,QAAQ,eAAe,CAAC,WAAW,OAAO,GAAG;GAChD,QAAQ,gBAAgB,MAAM;GAC9B,OAAO,OAAO,OAAO;EACvB;EAEF,KAAK,MAAM,WAAW,SAAS,iBAA8B,GAAG,cAAc,yBAAyB,GACrG,IAAI,WAAW,OAAO,GAAG;GACvB,QAAQ,aAAa,QAAQ,EAAE;GAC/B,OAAO,IAAI,OAAO;EACpB;CAEJ;CAEA,SAAS,UAAU,OAAc;EAC/B,IAAI,CAAC,YAAY,WAAW,EAAE,MAAM,kBAAkB,UAAU;EAChE,IAAI,iBAAiB,iBAAiB,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG;EAC3E,MAAM,SAAS,MAAM,OAAO,QAAqB,IAAI,OAAO,KAAK,cAAc,YAAY;EAC3F,IAAI,CAAC,UAAU,CAAC,WAAW,MAAM,GAAG;EACpC,MAAM,eAAe;EACrB,MAAM,yBAAyB;CACjC;CAEA,MAAM,WAAW,IAAI,iBAAiB,OAAO;CAC7C,MAAM,OAAO,8BAAA,eACL,YAAY,UACjB,YAAY;EACX,SAAS,WAAW;EACpB,QAAQ;EACR,IAAI,CAAC,SAAS;EACd,SAAS,KAAK,OAAO,KAAK;EAC1B,QAAQ;EACR,SAAS,QAAQ,SAAS,MAAM;GAC9B,WAAW;GACX,SAAS;GACT,eAAe;GACf,YAAY;GACZ,iBAAiB;IAAC;IAAS;IAAe;GAAO;EACnD,CAAC;CACH,GACA,EAAE,iBAAiB,KAAK,CAC1B;CACA,SAAS,iBAAiB,SAAS,WAAW,IAAI;CAClD,SAAS,iBAAiB,WAAW,WAAW,IAAI;CAEpD,aAAa;EACX,KAAK;EACL,SAAS,WAAW;EACpB,SAAS,oBAAoB,SAAS,WAAW,IAAI;EACrD,SAAS,oBAAoB,WAAW,WAAW,IAAI;EACvD,QAAQ;CACV;AACF"}
@@ -0,0 +1,51 @@
1
+ var AI_TERMINAL_MAX_BYTES = 32 * 1024;
2
+ var MAX_SOURCE_CHARACTERS = 1e6;
3
+ function redactAiTerminalText(text) {
4
+ text = text.replace(/\\\n/g, "");
5
+ const lines = text.split("\n");
6
+ let blockIndent;
7
+ for (let index = 0; index < lines.length; index++) {
8
+ const line = lines[index];
9
+ const indent = line.match(/^\s*/)?.[0].length ?? 0;
10
+ if (blockIndent !== void 0) {
11
+ if (!line.trim() || indent > blockIndent) {
12
+ lines[index] = "";
13
+ continue;
14
+ }
15
+ blockIndent = void 0;
16
+ }
17
+ const field = line.match(/^(\s*(?:-\s*)?)(client-key-data|client-certificate-data|token|password|passwd|secret|api[_-]?key|value)\s*:\s*(.*)$/i);
18
+ if (!field) continue;
19
+ lines[index] = `${field[1]}${field[2]}: [REDACTED]`;
20
+ if (!field[3].trim() || /^[|>]/.test(field[3])) blockIndent = indent;
21
+ }
22
+ return lines.join("\n").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g, "").replace(/\u001b\[[0-?]*[ -/]*[@-~]/g, "").replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g, "").replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g, "[REDACTED]").replace(/^[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, "[REDACTED]").replace(/\b([A-Za-z_][A-Za-z0-9_]*)=("(?:\\[\s\S]|[^"\\])*(?:"|$)|'[^']*(?:'|$)|[^\n]*)/g, "$1=[REDACTED]").replace(/(["'](?:password|passwd|token|secret|api[_-]?key|authorization)["']\s*:\s*)("(?:\\[\s\S]|[^"\\])*(?:"|$)|'[^']*(?:'|$))/gi, "$1\"[REDACTED]\"").replace(/(--(?:password|passwd|token|secret|api[_-]?key)(?:\s+|=))(?:("[^"\n]*"|'[^'\n]*')|[^\s]+)/gi, "$1[REDACTED]").replace(/\b(Bearer|Basic)\s+[^\s"']+/gi, "$1 [REDACTED]").replace(/\b((?:password|passwd|token|secret|api[_-]?key|authorization)\s*[:=]\s*)[^\n]+/gi, "$1[REDACTED]").replace(/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g, "[REDACTED]").replace(/\b(?:gh[pousr]_[A-Za-z0-9_]+|github_pat_[A-Za-z0-9_]+|sk-[A-Za-z0-9_-]{16,}|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)\b/g, "[REDACTED]").replace(/(https?:\/\/)[^\s/@]+:[^\s/@]+@/gi, "$1[REDACTED]@");
23
+ }
24
+ function sanitizeAiTerminalSnapshot(value) {
25
+ if (!value || typeof value !== "object") return;
26
+ const input = value;
27
+ if (typeof input.text !== "string" || input.text.length > MAX_SOURCE_CHARACTERS || typeof input.capturedAt !== "string" || input.capturedAt.length > 40 || !Number.isFinite(Date.parse(input.capturedAt))) return;
28
+ const lines = redactAiTerminalText(input.text.replace(/\r\n?/g, "\n")).split("\n");
29
+ while (lines.length && !lines[lines.length - 1].trim()) lines.pop();
30
+ const tail = [];
31
+ let bytes = 0;
32
+ for (let index = lines.length - 1; index >= 0 && tail.length < 300; index--) {
33
+ const line = lines[index];
34
+ const size = new TextEncoder().encode(line).length + (tail.length ? 1 : 0);
35
+ if (bytes + size > 32768) break;
36
+ bytes += size;
37
+ tail.unshift(line);
38
+ }
39
+ if (!tail.length || !tail.some((line) => line.trim())) return;
40
+ return {
41
+ text: tail.join("\n"),
42
+ capturedAt: new Date(input.capturedAt).toISOString(),
43
+ truncated: input.truncated === true || tail.length < lines.length
44
+ };
45
+ }
46
+ //#endregion
47
+ exports.AI_TERMINAL_MAX_BYTES = AI_TERMINAL_MAX_BYTES;
48
+ exports.redactAiTerminalText = redactAiTerminalText;
49
+ exports.sanitizeAiTerminalSnapshot = sanitizeAiTerminalSnapshot;
50
+
51
+ //# sourceMappingURL=ai-terminal-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-terminal-context.js","names":[],"sources":["../../../../src/common/ai-terminal-context.ts"],"sourcesContent":["export const AI_TERMINAL_MAX_ROWS = 300;\nexport const AI_TERMINAL_MAX_BYTES = 32 * 1024;\nconst MAX_SOURCE_CHARACTERS = 1_000_000;\n\nexport interface AiTerminalSnapshot {\n text: string;\n capturedAt: string;\n truncated: boolean;\n}\n\nexport function redactAiTerminalText(text: string): string {\n // collapse shell continuations before matching assignments so their values stay together\n text = text.replace(/\\\\\\n/g, \"\");\n const lines = text.split(\"\\n\");\n let blockIndent: number | undefined;\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index];\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (blockIndent !== undefined) {\n if (!line.trim() || indent > blockIndent) {\n lines[index] = \"\";\n continue;\n }\n blockIndent = undefined;\n }\n const field = line.match(\n /^(\\s*(?:-\\s*)?)(client-key-data|client-certificate-data|token|password|passwd|secret|api[_-]?key|value)\\s*:\\s*(.*)$/i,\n );\n if (!field) continue;\n lines[index] = `${field[1]}${field[2]}: [REDACTED]`;\n if (!field[3].trim() || /^[|>]/.test(field[3])) blockIndent = indent;\n }\n return lines\n .join(\"\\n\")\n .replace(/\\u001b\\][^\\u0007]*(?:\\u0007|\\u001b\\\\)/g, \"\")\n .replace(/\\u001b\\[[0-?]*[ -/]*[@-~]/g, \"\")\n .replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f]/g, \"\")\n .replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\\s\\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g, \"[REDACTED]\")\n .replace(/^[\\s\\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, \"[REDACTED]\")\n .replace(/\\b([A-Za-z_][A-Za-z0-9_]*)=(\"(?:\\\\[\\s\\S]|[^\"\\\\])*(?:\"|$)|'[^']*(?:'|$)|[^\\n]*)/g, \"$1=[REDACTED]\")\n .replace(\n /([\"'](?:password|passwd|token|secret|api[_-]?key|authorization)[\"']\\s*:\\s*)(\"(?:\\\\[\\s\\S]|[^\"\\\\])*(?:\"|$)|'[^']*(?:'|$))/gi,\n '$1\"[REDACTED]\"',\n )\n .replace(\n /(--(?:password|passwd|token|secret|api[_-]?key)(?:\\s+|=))(?:(\"[^\"\\n]*\"|'[^'\\n]*')|[^\\s]+)/gi,\n \"$1[REDACTED]\",\n )\n .replace(/\\b(Bearer|Basic)\\s+[^\\s\"']+/gi, \"$1 [REDACTED]\")\n .replace(/\\b((?:password|passwd|token|secret|api[_-]?key|authorization)\\s*[:=]\\s*)[^\\n]+/gi, \"$1[REDACTED]\")\n .replace(/\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b/g, \"[REDACTED]\")\n .replace(\n /\\b(?:gh[pousr]_[A-Za-z0-9_]+|github_pat_[A-Za-z0-9_]+|sk-[A-Za-z0-9_-]{16,}|eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)\\b/g,\n \"[REDACTED]\",\n )\n .replace(/(https?:\\/\\/)[^\\s/@]+:[^\\s/@]+@/gi, \"$1[REDACTED]@\");\n}\n\nexport function sanitizeAiTerminalSnapshot(value: unknown): AiTerminalSnapshot | undefined {\n if (!value || typeof value !== \"object\") return;\n const input = value as Record<string, unknown>;\n if (\n typeof input.text !== \"string\" ||\n input.text.length > MAX_SOURCE_CHARACTERS ||\n typeof input.capturedAt !== \"string\" ||\n input.capturedAt.length > 40 ||\n !Number.isFinite(Date.parse(input.capturedAt))\n )\n return;\n // redact the complete input before truncation to preserve multiline assignment boundaries\n const safe = redactAiTerminalText(input.text.replace(/\\r\\n?/g, \"\\n\"));\n const lines = safe.split(\"\\n\");\n while (lines.length && !lines[lines.length - 1].trim()) lines.pop();\n const tail: string[] = [];\n let bytes = 0;\n for (let index = lines.length - 1; index >= 0 && tail.length < AI_TERMINAL_MAX_ROWS; index--) {\n const line = lines[index];\n const size = new TextEncoder().encode(line).length + (tail.length ? 1 : 0);\n if (bytes + size > AI_TERMINAL_MAX_BYTES) break;\n bytes += size;\n tail.unshift(line);\n }\n if (!tail.length || !tail.some((line) => line.trim())) return;\n return {\n text: tail.join(\"\\n\"),\n capturedAt: new Date(input.capturedAt).toISOString(),\n truncated: input.truncated === true || tail.length < lines.length,\n };\n}\n"],"mappings":"AACA,IAAa,wBAAwB,KAAK;AAC1C,IAAM,wBAAwB;AAQ9B,SAAgB,qBAAqB,MAAsB;CAEzD,OAAO,KAAK,QAAQ,SAAS,EAAE;CAC/B,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,IAAI;CACJ,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;EACjD,MAAM,OAAO,MAAM;EACnB,MAAM,SAAS,KAAK,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU;EACjD,IAAI,gBAAgB,KAAA,GAAW;GAC7B,IAAI,CAAC,KAAK,KAAK,KAAK,SAAS,aAAa;IACxC,MAAM,SAAS;IACf;GACF;GACA,cAAc,KAAA;EAChB;EACA,MAAM,QAAQ,KAAK,MACjB,sHACF;EACA,IAAI,CAAC,OAAO;EACZ,MAAM,SAAS,GAAG,MAAM,KAAK,MAAM,GAAG;EACtC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,KAAK,QAAQ,KAAK,MAAM,EAAE,GAAG,cAAc;CAChE;CACA,OAAO,MACJ,KAAK,IAAI,CAAC,CACV,QAAQ,0CAA0C,EAAE,CAAC,CACrD,QAAQ,8BAA8B,EAAE,CAAC,CACzC,QAAQ,8CAA8C,EAAE,CAAC,CACzD,QAAQ,qFAAqF,YAAY,CAAC,CAC1G,QAAQ,8CAA8C,YAAY,CAAC,CACnE,QAAQ,mFAAmF,eAAe,CAAC,CAC3G,QACC,6HACA,kBACF,CAAC,CACA,QACC,+FACA,cACF,CAAC,CACA,QAAQ,iCAAiC,eAAe,CAAC,CACzD,QAAQ,oFAAoF,cAAc,CAAC,CAC3G,QAAQ,kCAAkC,YAAY,CAAC,CACvD,QACC,qIACA,YACF,CAAC,CACA,QAAQ,qCAAqC,eAAe;AACjE;AAEA,SAAgB,2BAA2B,OAAgD;CACzF,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU;CACzC,MAAM,QAAQ;CACd,IACE,OAAO,MAAM,SAAS,YACtB,MAAM,KAAK,SAAS,yBACpB,OAAO,MAAM,eAAe,YAC5B,MAAM,WAAW,SAAS,MAC1B,CAAC,OAAO,SAAS,KAAK,MAAM,MAAM,UAAU,CAAC,GAE7C;CAGF,MAAM,QADO,qBAAqB,MAAM,KAAK,QAAQ,UAAU,IAAI,CACrD,CAAA,CAAK,MAAM,IAAI;CAC7B,OAAO,MAAM,UAAU,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,KAAK,GAAG,MAAM,IAAI;CAClE,MAAM,OAAiB,CAAC;CACxB,IAAI,QAAQ;CACZ,KAAK,IAAI,QAAQ,MAAM,SAAS,GAAG,SAAS,KAAK,KAAK,SAAA,KAA+B,SAAS;EAC5F,MAAM,OAAO,MAAM;EACnB,MAAM,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI;EACxE,IAAI,QAAQ,OAAA,OAA8B;EAC1C,SAAS;EACT,KAAK,QAAQ,IAAI;CACnB;CACA,IAAI,CAAC,KAAK,UAAU,CAAC,KAAK,MAAM,SAAS,KAAK,KAAK,CAAC,GAAG;CACvD,OAAO;EACL,MAAM,KAAK,KAAK,IAAI;EACpB,YAAY,IAAI,KAAK,MAAM,UAAU,CAAC,CAAC,YAAY;EACnD,WAAW,MAAM,cAAc,QAAQ,KAAK,SAAS,MAAM;CAC7D;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","names":[],"sources":["../../../../src/common/ai.ts"],"sourcesContent":["import type { AiResourceReference } from \"./ai-extras\";\n\nexport type AiProvider = \"codex\" | \"claude\";\n\nexport interface AiReadActivity {\n method: \"pods\" | \"nodes\" | \"resources\" | \"logs\";\n status: \"ok\" | \"unavailable\";\n}\n\nexport interface AiChatMessage {\n role: \"user\" | \"assistant\";\n text: string;\n}\n\nexport interface AiChatRequest {\n provider?: AiProvider;\n requestId?: string;\n messages: AiChatMessage[];\n context: {\n clusterId?: string;\n screen?: string;\n resource?: { kind?: string; namespace?: string; name?: string };\n };\n systemPrompt?: string;\n reasoningEffort?: string;\n model: string;\n speed: \"default\" | \"fast\";\n}\n\nexport interface AiChatResponse {\n references?: AiResourceReference[];\n provider?: AiProvider;\n text: string;\n reads?: AiReadActivity[];\n}\n\nexport const AI_CHAT_CHANNEL = \"freelens-power:ai-chat\";\n\nexport type AiFailureCode =\n | \"CLI_FAILURE\"\n | \"INVALID_REPLY\"\n | \"READ_LIMIT\"\n | \"TIMEOUT\"\n | \"CANCELLED\"\n | \"INPUT_LIMIT\"\n | \"UNAVAILABLE\"\n | \"UNSAFE_POLICY\";\n\nexport interface AiReadActivityEvent {\n requestId: string;\n method: AiReadActivity[\"method\"];\n status: \"reading\" | \"ok\" | \"unavailable\";\n}\n\nexport const AI_READ_ACTIVITY_CHANNEL = \"freelens-power:ai-read-activity\";\n\nexport function validAiRequestId(value: unknown): value is string {\n return typeof value === \"string\" && /^[a-zA-Z0-9_-]{1,100}$/.test(value);\n}\n"],"mappings":";AAoCA,IAAa,kBAAkB;AAkB/B,IAAa,2BAA2B"}
1
+ {"version":3,"file":"ai.js","names":[],"sources":["../../../../src/common/ai.ts"],"sourcesContent":["import type { AiResourceReference } from \"./ai-extras\";\n\nexport type AiProvider = \"codex\" | \"claude\";\n\nexport interface AiReadActivity {\n method: \"pods\" | \"nodes\" | \"resources\" | \"logs\";\n status: \"ok\" | \"unavailable\";\n}\n\nexport interface AiChatMessage {\n role: \"user\" | \"assistant\";\n text: string;\n}\n\nexport interface AiChatRequest {\n provider?: AiProvider;\n terminalSnapshot?: import(\"./ai-terminal-context\").AiTerminalSnapshot;\n requestId?: string;\n messages: AiChatMessage[];\n context: {\n clusterId?: string;\n screen?: string;\n resource?: { kind?: string; namespace?: string; name?: string };\n };\n systemPrompt?: string;\n reasoningEffort?: string;\n model: string;\n speed: \"default\" | \"fast\";\n}\n\nexport interface AiChatResponse {\n references?: AiResourceReference[];\n provider?: AiProvider;\n text: string;\n reads?: AiReadActivity[];\n}\n\nexport const AI_CHAT_CHANNEL = \"freelens-power:ai-chat\";\n\nexport type AiFailureCode =\n | \"CLI_FAILURE\"\n | \"INVALID_REPLY\"\n | \"READ_LIMIT\"\n | \"TIMEOUT\"\n | \"CANCELLED\"\n | \"INPUT_LIMIT\"\n | \"UNAVAILABLE\"\n | \"UNSAFE_POLICY\";\n\nexport interface AiReadActivityEvent {\n requestId: string;\n method: AiReadActivity[\"method\"];\n status: \"reading\" | \"ok\" | \"unavailable\";\n}\n\nexport const AI_READ_ACTIVITY_CHANNEL = \"freelens-power:ai-read-activity\";\n\nexport function validAiRequestId(value: unknown): value is string {\n return typeof value === \"string\" && /^[a-zA-Z0-9_-]{1,100}$/.test(value);\n}\n"],"mappings":";AAqCA,IAAa,kBAAkB;AAkB/B,IAAa,2BAA2B"}
@@ -0,0 +1,6 @@
1
+ //#region src/common/cluster-icon-ipc.ts
2
+ var CLUSTER_ICONS_CHANNEL = "freelens-power:cluster-icons";
3
+ //#endregion
4
+ exports.CLUSTER_ICONS_CHANNEL = CLUSTER_ICONS_CHANNEL;
5
+
6
+ //# sourceMappingURL=cluster-icon-ipc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-icon-ipc.js","names":[],"sources":["../../../../src/common/cluster-icon-ipc.ts"],"sourcesContent":["import type { ClusterIconDesign } from \"./cluster-icons\";\n\nexport const CLUSTER_ICONS_CHANNEL = \"freelens-power:cluster-icons\";\n\nexport interface ClusterIconEntry {\n id: string;\n name: string;\n icon?: string;\n design?: ClusterIconDesign;\n customized: boolean;\n}\n\nexport type ClusterIconRequest = { operation: \"list\" } | { operation: \"apply\"; id: string; design: ClusterIconDesign };\n"],"mappings":";AAEA,IAAa,wBAAwB"}
@@ -0,0 +1,133 @@
1
+ //#region src/common/cluster-icons.ts
2
+ var GLYPHS = Object.freeze([
3
+ Object.freeze({
4
+ id: "window",
5
+ label: "Window",
6
+ body: "<g transform=\"translate(32 11.4) scale(1.168000000) translate(-32 -14)\" stroke-width=\"2.397260274\"><rect x=\"16\" y=\"14\" width=\"32\" height=\"25\" rx=\"4\"/><path d=\"M16 22h32M23 18h.1M28 18h.1M24 28l-4 3 4 3M35 28h7M35 34h5\"/></g>"
7
+ }),
8
+ Object.freeze({
9
+ id: "server",
10
+ label: "Server",
11
+ body: "<g transform=\"translate(32 11.4) scale(1.006896552) translate(-32 -13)\" stroke-width=\"2.780821917\"><rect x=\"17\" y=\"13\" width=\"30\" height=\"12\" rx=\"4\"/><rect x=\"17\" y=\"30\" width=\"30\" height=\"12\" rx=\"4\"/><path d=\"M23 19h.1M23 36h.1M32 19h8M32 36h8\"/></g>"
12
+ }),
13
+ Object.freeze({
14
+ id: "database",
15
+ label: "Database",
16
+ body: "<g transform=\"translate(32 11.4) scale(0.941935484) translate(-32 -11)\" stroke-width=\"2.972602739\"><ellipse cx=\"32\" cy=\"17\" rx=\"15\" ry=\"6\"/><path d=\"M17 17v19c0 8 30 8 30 0V17M17 26c0 8 30 8 30 0\"/></g>"
17
+ }),
18
+ Object.freeze({
19
+ id: "briefcase",
20
+ label: "Briefcase",
21
+ body: "<g transform=\"translate(32 11.4) scale(0.973333333) translate(-32 -13)\" stroke-width=\"2.876712330\"><rect x=\"14\" y=\"20\" width=\"36\" height=\"23\" rx=\"4\"/><path d=\"M25 20v-5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v5M14 28c10 7 26 7 36 0\"/><rect x=\"29\" y=\"29\" width=\"6\" height=\"7\" rx=\"1.5\" fill=\"#292d38\"/></g>"
22
+ }),
23
+ Object.freeze({
24
+ id: "sailboat",
25
+ label: "Sailboat",
26
+ body: "<g transform=\"translate(32 11.4) scale(0.834285714) translate(-32 -11)\" stroke-width=\"3.356164385\"><path d=\"M31 11v23H17zM36 18l11 16H36zM13 39h38l-7 7H21z\"/></g>"
27
+ }),
28
+ Object.freeze({
29
+ id: "network",
30
+ label: "Network",
31
+ body: "<g transform=\"translate(32 11.4) scale(0.768421053) translate(-32 -7)\" stroke-width=\"3.643835615\"><circle cx=\"32\" cy=\"26\" r=\"7\"/><path d=\"M32 13v6M32 33v6M19 26h6M39 26h6\"/><circle cx=\"32\" cy=\"10\" r=\"3\"/><circle cx=\"32\" cy=\"42\" r=\"3\"/><circle cx=\"16\" cy=\"26\" r=\"3\"/><circle cx=\"48\" cy=\"26\" r=\"3\"/></g>"
32
+ }),
33
+ Object.freeze({
34
+ id: "box",
35
+ label: "Box",
36
+ body: "<g transform=\"translate(32 11.4) scale(0.834285714) translate(-32 -11)\" stroke-width=\"3.356164385\"><path d=\"M32 11l17 10v17L32 46 15 38V21zM15 21l17 9 17-9M32 30v16\"/></g>"
37
+ }),
38
+ Object.freeze({
39
+ id: "blocks",
40
+ label: "Blocks",
41
+ body: "<rect x=\"17\" y=\"11.4\" width=\"10\" height=\"9\" rx=\"1.6\"/><rect x=\"37\" y=\"11.4\" width=\"10\" height=\"9\" rx=\"1.6\"/><rect x=\"27\" y=\"31.6\" width=\"10\" height=\"9\" rx=\"1.6\"/><path d=\"M22 20.4V26h20v-5.6M32 26v5.6\"/>"
42
+ }),
43
+ Object.freeze({
44
+ id: "git-branch",
45
+ label: "Git branch",
46
+ body: "<g transform=\"translate(32 11.4) scale(0.973333333) translate(-32 -12)\" stroke-width=\"2.876712330\"><circle cx=\"22\" cy=\"16\" r=\"4\"/><circle cx=\"42\" cy=\"16\" r=\"4\"/><circle cx=\"22\" cy=\"38\" r=\"4\"/><path d=\"M22 20v14M42 20c0 10-20 3-20 13\"/></g>"
47
+ }),
48
+ Object.freeze({
49
+ id: "cloud",
50
+ label: "Cloud",
51
+ body: "<path d=\"M22 40.6c-6 0-10-4-10-10 0-5 3-9 8-10 0-5 5-9.2 12-9.2s12 5 12 12c5 0 8 4 8 9 0 5-4 8.2-9 8.2z\"/>"
52
+ }),
53
+ Object.freeze({
54
+ id: "cpu",
55
+ label: "CPU",
56
+ body: "<rect x=\"21\" y=\"15\" width=\"22\" height=\"22\" rx=\"4\"/><rect x=\"27\" y=\"21\" width=\"10\" height=\"10\" rx=\"1\"/><path d=\"M26 11.4V15M32 11.4V15M38 11.4V15M26 37v3.6M32 37v3.6M38 37v3.6M17.4 20H21M17.4 26H21M17.4 32H21M43 20h3.6M43 26h3.6M43 32h3.6\"/>"
57
+ }),
58
+ Object.freeze({
59
+ id: "shield",
60
+ label: "Shield",
61
+ body: "<path d=\"M32 11.4l13 5v10c0 7-6 12-13 14.2C25 38.4 19 33.4 19 26.4v-10zM25 26l5 5 9-10\"/>"
62
+ }),
63
+ Object.freeze({
64
+ id: "globe",
65
+ label: "Globe",
66
+ body: "<circle cx=\"32\" cy=\"26\" r=\"14.6\"/><ellipse cx=\"32\" cy=\"26\" rx=\"6.5\" ry=\"14.6\"/><path d=\"M17.4 26h29.2M20.2 17.5h23.6M20.2 34.5h23.6\"/>"
67
+ }),
68
+ Object.freeze({
69
+ id: "key",
70
+ label: "Key",
71
+ body: "<g transform=\"translate(32 11.4) scale(1.39047619) translate(-12.5 -1)\" stroke-width=\"2.01369863\"><path d=\"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\".5\" stroke-width=\"1\"/></g>"
72
+ }),
73
+ Object.freeze({
74
+ id: "rocket",
75
+ label: "Rocket",
76
+ body: "<g transform=\"translate(32 11.4) scale(1.497435897) translate(-12.25 -2)\" stroke-width=\"1.869863014\"><path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2zM9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05\"/></g>"
77
+ })
78
+ ]);
79
+ var COLOR = /^#[\da-f]{6}$/i;
80
+ var LABEL = /^[\p{L}\p{N}\p{M}\p{P}\p{S} ]*$/u;
81
+ function normalizeClusterIconDesign(input) {
82
+ if (!input || typeof input !== "object" || Array.isArray(input)) throw new Error("Invalid cluster icon design");
83
+ const value = input;
84
+ if (typeof value.label !== "string" || !LABEL.test(value.label)) throw new Error("Use up to three visible characters for the label");
85
+ const label = value.label.normalize("NFC").trim();
86
+ if (Array.from(label).length > 3) throw new Error("Use up to three visible characters for the label");
87
+ if (typeof value.glyph !== "string" || !GLYPHS.some((glyph) => glyph.id === value.glyph)) throw new Error("Choose an available cluster icon");
88
+ for (const key of [
89
+ "outlineColor",
90
+ "labelColor",
91
+ "iconColor"
92
+ ]) if (typeof value[key] !== "string" || !COLOR.test(value[key])) throw new Error("Use a six-digit hexadecimal color");
93
+ return {
94
+ label,
95
+ glyph: value.glyph,
96
+ outlineColor: value.outlineColor.toLowerCase(),
97
+ labelColor: value.labelColor.toLowerCase(),
98
+ iconColor: value.iconColor.toLowerCase()
99
+ };
100
+ }
101
+ function defaultClusterIconDesign(name) {
102
+ const words = name.normalize("NFC").match(/[\p{L}\p{N}][\p{L}\p{N}\p{M}]*/gu) ?? [];
103
+ const abbreviation = words.length > 1 ? words.map((word) => Array.from(word)[0]).join("") : words[0] ?? "K8S";
104
+ return {
105
+ label: Array.from(abbreviation.toUpperCase()).slice(0, 3).join(""),
106
+ outlineColor: "#b49aff",
107
+ labelColor: "#b49aff",
108
+ glyph: "network",
109
+ iconColor: "#b49aff"
110
+ };
111
+ }
112
+ function escapeXml(text) {
113
+ return text.replace(/[&<>"']/g, (character) => ({
114
+ "&": "&amp;",
115
+ "<": "&lt;",
116
+ ">": "&gt;",
117
+ "\"": "&quot;",
118
+ "'": "&apos;"
119
+ })[character]);
120
+ }
121
+ function clusterIconDataUrl(input) {
122
+ const design = normalizeClusterIconDesign(input);
123
+ const glyph = GLYPHS.find((candidate) => candidate.id === design.glyph);
124
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 64 64"><rect x="2" y="2" width="60" height="60" rx="15" fill="#292d38" stroke="${design.outlineColor}" stroke-width="3"/><g fill="none" stroke="${design.iconColor}" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round">${glyph.body}</g><rect x="15" y="46" width="34" height="12" rx="6" fill="${design.labelColor}"/><text x="32" y="55.2" text-anchor="middle" font-family="Helvetica,Arial,sans-serif" font-size="9.5" font-weight="800" fill="#292d38">${escapeXml(design.label)}</text></svg>`;
125
+ return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
126
+ }
127
+ //#endregion
128
+ exports.GLYPHS = GLYPHS;
129
+ exports.clusterIconDataUrl = clusterIconDataUrl;
130
+ exports.defaultClusterIconDesign = defaultClusterIconDesign;
131
+ exports.normalizeClusterIconDesign = normalizeClusterIconDesign;
132
+
133
+ //# sourceMappingURL=cluster-icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-icons.js","names":[],"sources":["../../../../src/common/cluster-icons.ts"],"sourcesContent":["export interface ClusterIconDesign {\n label: string;\n outlineColor: string;\n labelColor: string;\n glyph: string;\n iconColor: string;\n}\n\n// glyphs share the reference fitting, with Lucide contours for [key] and [rocket]\nexport const GLYPHS = Object.freeze([\n Object.freeze({\n id: \"window\",\n label: \"Window\",\n body: '<g transform=\"translate(32 11.4) scale(1.168000000) translate(-32 -14)\" stroke-width=\"2.397260274\"><rect x=\"16\" y=\"14\" width=\"32\" height=\"25\" rx=\"4\"/><path d=\"M16 22h32M23 18h.1M28 18h.1M24 28l-4 3 4 3M35 28h7M35 34h5\"/></g>',\n }),\n Object.freeze({\n id: \"server\",\n label: \"Server\",\n body: '<g transform=\"translate(32 11.4) scale(1.006896552) translate(-32 -13)\" stroke-width=\"2.780821917\"><rect x=\"17\" y=\"13\" width=\"30\" height=\"12\" rx=\"4\"/><rect x=\"17\" y=\"30\" width=\"30\" height=\"12\" rx=\"4\"/><path d=\"M23 19h.1M23 36h.1M32 19h8M32 36h8\"/></g>',\n }),\n Object.freeze({\n id: \"database\",\n label: \"Database\",\n body: '<g transform=\"translate(32 11.4) scale(0.941935484) translate(-32 -11)\" stroke-width=\"2.972602739\"><ellipse cx=\"32\" cy=\"17\" rx=\"15\" ry=\"6\"/><path d=\"M17 17v19c0 8 30 8 30 0V17M17 26c0 8 30 8 30 0\"/></g>',\n }),\n Object.freeze({\n id: \"briefcase\",\n label: \"Briefcase\",\n body: '<g transform=\"translate(32 11.4) scale(0.973333333) translate(-32 -13)\" stroke-width=\"2.876712330\"><rect x=\"14\" y=\"20\" width=\"36\" height=\"23\" rx=\"4\"/><path d=\"M25 20v-5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v5M14 28c10 7 26 7 36 0\"/><rect x=\"29\" y=\"29\" width=\"6\" height=\"7\" rx=\"1.5\" fill=\"#292d38\"/></g>',\n }),\n Object.freeze({\n id: \"sailboat\",\n label: \"Sailboat\",\n body: '<g transform=\"translate(32 11.4) scale(0.834285714) translate(-32 -11)\" stroke-width=\"3.356164385\"><path d=\"M31 11v23H17zM36 18l11 16H36zM13 39h38l-7 7H21z\"/></g>',\n }),\n Object.freeze({\n id: \"network\",\n label: \"Network\",\n body: '<g transform=\"translate(32 11.4) scale(0.768421053) translate(-32 -7)\" stroke-width=\"3.643835615\"><circle cx=\"32\" cy=\"26\" r=\"7\"/><path d=\"M32 13v6M32 33v6M19 26h6M39 26h6\"/><circle cx=\"32\" cy=\"10\" r=\"3\"/><circle cx=\"32\" cy=\"42\" r=\"3\"/><circle cx=\"16\" cy=\"26\" r=\"3\"/><circle cx=\"48\" cy=\"26\" r=\"3\"/></g>',\n }),\n Object.freeze({\n id: \"box\",\n label: \"Box\",\n body: '<g transform=\"translate(32 11.4) scale(0.834285714) translate(-32 -11)\" stroke-width=\"3.356164385\"><path d=\"M32 11l17 10v17L32 46 15 38V21zM15 21l17 9 17-9M32 30v16\"/></g>',\n }),\n Object.freeze({\n id: \"blocks\",\n label: \"Blocks\",\n body: '<rect x=\"17\" y=\"11.4\" width=\"10\" height=\"9\" rx=\"1.6\"/><rect x=\"37\" y=\"11.4\" width=\"10\" height=\"9\" rx=\"1.6\"/><rect x=\"27\" y=\"31.6\" width=\"10\" height=\"9\" rx=\"1.6\"/><path d=\"M22 20.4V26h20v-5.6M32 26v5.6\"/>',\n }),\n Object.freeze({\n id: \"git-branch\",\n label: \"Git branch\",\n body: '<g transform=\"translate(32 11.4) scale(0.973333333) translate(-32 -12)\" stroke-width=\"2.876712330\"><circle cx=\"22\" cy=\"16\" r=\"4\"/><circle cx=\"42\" cy=\"16\" r=\"4\"/><circle cx=\"22\" cy=\"38\" r=\"4\"/><path d=\"M22 20v14M42 20c0 10-20 3-20 13\"/></g>',\n }),\n Object.freeze({\n id: \"cloud\",\n label: \"Cloud\",\n body: '<path d=\"M22 40.6c-6 0-10-4-10-10 0-5 3-9 8-10 0-5 5-9.2 12-9.2s12 5 12 12c5 0 8 4 8 9 0 5-4 8.2-9 8.2z\"/>',\n }),\n Object.freeze({\n id: \"cpu\",\n label: \"CPU\",\n body: '<rect x=\"21\" y=\"15\" width=\"22\" height=\"22\" rx=\"4\"/><rect x=\"27\" y=\"21\" width=\"10\" height=\"10\" rx=\"1\"/><path d=\"M26 11.4V15M32 11.4V15M38 11.4V15M26 37v3.6M32 37v3.6M38 37v3.6M17.4 20H21M17.4 26H21M17.4 32H21M43 20h3.6M43 26h3.6M43 32h3.6\"/>',\n }),\n Object.freeze({\n id: \"shield\",\n label: \"Shield\",\n body: '<path d=\"M32 11.4l13 5v10c0 7-6 12-13 14.2C25 38.4 19 33.4 19 26.4v-10zM25 26l5 5 9-10\"/>',\n }),\n Object.freeze({\n id: \"globe\",\n label: \"Globe\",\n body: '<circle cx=\"32\" cy=\"26\" r=\"14.6\"/><ellipse cx=\"32\" cy=\"26\" rx=\"6.5\" ry=\"14.6\"/><path d=\"M17.4 26h29.2M20.2 17.5h23.6M20.2 34.5h23.6\"/>',\n }),\n Object.freeze({\n id: \"key\",\n label: \"Key\",\n body: '<g transform=\"translate(32 11.4) scale(1.39047619) translate(-12.5 -1)\" stroke-width=\"2.01369863\"><path d=\"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\".5\" stroke-width=\"1\"/></g>',\n }),\n Object.freeze({\n id: \"rocket\",\n label: \"Rocket\",\n body: '<g transform=\"translate(32 11.4) scale(1.497435897) translate(-12.25 -2)\" stroke-width=\"1.869863014\"><path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2zM9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05\"/></g>',\n }),\n]);\nconst COLOR = /^#[\\da-f]{6}$/i;\nconst LABEL = /^[\\p{L}\\p{N}\\p{M}\\p{P}\\p{S} ]*$/u;\n\nexport function normalizeClusterIconDesign(input: unknown): ClusterIconDesign {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) {\n throw new Error(\"Invalid cluster icon design\");\n }\n const value = input as Record<string, unknown>;\n if (typeof value.label !== \"string\" || !LABEL.test(value.label)) {\n throw new Error(\"Use up to three visible characters for the label\");\n }\n const label = value.label.normalize(\"NFC\").trim();\n if (Array.from(label).length > 3) {\n throw new Error(\"Use up to three visible characters for the label\");\n }\n if (typeof value.glyph !== \"string\" || !GLYPHS.some((glyph) => glyph.id === value.glyph)) {\n throw new Error(\"Choose an available cluster icon\");\n }\n const colors = [\"outlineColor\", \"labelColor\", \"iconColor\"] as const;\n for (const key of colors) {\n if (typeof value[key] !== \"string\" || !COLOR.test(value[key] as string)) {\n throw new Error(\"Use a six-digit hexadecimal color\");\n }\n }\n return {\n label,\n glyph: value.glyph,\n outlineColor: (value.outlineColor as string).toLowerCase(),\n labelColor: (value.labelColor as string).toLowerCase(),\n iconColor: (value.iconColor as string).toLowerCase(),\n };\n}\n\nexport function defaultClusterIconDesign(name: string): ClusterIconDesign {\n const words = name.normalize(\"NFC\").match(/[\\p{L}\\p{N}][\\p{L}\\p{N}\\p{M}]*/gu) ?? [];\n const abbreviation = words.length > 1 ? words.map((word) => Array.from(word)[0]).join(\"\") : (words[0] ?? \"K8S\");\n return {\n label: Array.from(abbreviation.toUpperCase()).slice(0, 3).join(\"\"),\n outlineColor: \"#b49aff\",\n labelColor: \"#b49aff\",\n glyph: \"network\",\n iconColor: \"#b49aff\",\n };\n}\n\nfunction escapeXml(text: string): string {\n return text.replace(\n /[&<>\"']/g,\n (character) => ({ \"&\": \"&amp;\", \"<\": \"&lt;\", \">\": \"&gt;\", '\"': \"&quot;\", \"'\": \"&apos;\" })[character]!,\n );\n}\n\nexport function clusterIconDataUrl(input: ClusterIconDesign): string {\n const design = normalizeClusterIconDesign(input);\n const glyph = GLYPHS.find((candidate) => candidate.id === design.glyph)!;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"256\" height=\"256\" viewBox=\"0 0 64 64\"><rect x=\"2\" y=\"2\" width=\"60\" height=\"60\" rx=\"15\" fill=\"#292d38\" stroke=\"${design.outlineColor}\" stroke-width=\"3\"/><g fill=\"none\" stroke=\"${design.iconColor}\" stroke-width=\"2.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${glyph.body}</g><rect x=\"15\" y=\"46\" width=\"34\" height=\"12\" rx=\"6\" fill=\"${design.labelColor}\"/><text x=\"32\" y=\"55.2\" text-anchor=\"middle\" font-family=\"Helvetica,Arial,sans-serif\" font-size=\"9.5\" font-weight=\"800\" fill=\"#292d38\">${escapeXml(design.label)}</text></svg>`;\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n}\n"],"mappings":";AASA,IAAa,SAAS,OAAO,OAAO;CAClC,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;CACD,OAAO,OAAO;EACZ,IAAI;EACJ,OAAO;EACP,MAAM;CACR,CAAC;AACH,CAAC;AACD,IAAM,QAAQ;AACd,IAAM,QAAQ;AAEd,SAAgB,2BAA2B,OAAmC;CAC5E,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAC5D,MAAM,IAAI,MAAM,6BAA6B;CAE/C,MAAM,QAAQ;CACd,IAAI,OAAO,MAAM,UAAU,YAAY,CAAC,MAAM,KAAK,MAAM,KAAK,GAC5D,MAAM,IAAI,MAAM,kDAAkD;CAEpE,MAAM,QAAQ,MAAM,MAAM,UAAU,KAAK,CAAC,CAAC,KAAK;CAChD,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,SAAS,GAC7B,MAAM,IAAI,MAAM,kDAAkD;CAEpE,IAAI,OAAO,MAAM,UAAU,YAAY,CAAC,OAAO,MAAM,UAAU,MAAM,OAAO,MAAM,KAAK,GACrF,MAAM,IAAI,MAAM,kCAAkC;CAGpD,KAAK,MAAM,OAAO;EADF;EAAgB;EAAc;CAC5B,GAChB,IAAI,OAAO,MAAM,SAAS,YAAY,CAAC,MAAM,KAAK,MAAM,IAAc,GACpE,MAAM,IAAI,MAAM,mCAAmC;CAGvD,OAAO;EACL;EACA,OAAO,MAAM;EACb,cAAe,MAAM,aAAwB,YAAY;EACzD,YAAa,MAAM,WAAsB,YAAY;EACrD,WAAY,MAAM,UAAqB,YAAY;CACrD;AACF;AAEA,SAAgB,yBAAyB,MAAiC;CACxE,MAAM,QAAQ,KAAK,UAAU,KAAK,CAAC,CAAC,MAAM,kCAAkC,KAAK,CAAC;CAClF,MAAM,eAAe,MAAM,SAAS,IAAI,MAAM,KAAK,SAAS,MAAM,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAK,MAAM,MAAM;CACzG,OAAO;EACL,OAAO,MAAM,KAAK,aAAa,YAAY,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;EACjE,cAAc;EACd,YAAY;EACZ,OAAO;EACP,WAAW;CACb;AACF;AAEA,SAAS,UAAU,MAAsB;CACvC,OAAO,KAAK,QACV,aACC,eAAe;EAAE,KAAK;EAAS,KAAK;EAAQ,KAAK;EAAQ,MAAK;EAAU,KAAK;CAAS,EAAA,CAAG,UAC5F;AACF;AAEA,SAAgB,mBAAmB,OAAkC;CACnE,MAAM,SAAS,2BAA2B,KAAK;CAC/C,MAAM,QAAQ,OAAO,MAAM,cAAc,UAAU,OAAO,OAAO,KAAK;CACtE,MAAM,MAAM,gKAAgK,OAAO,aAAa,6CAA6C,OAAO,UAAU,sEAAsE,MAAM,KAAK,8DAA8D,OAAO,WAAW,0IAA0I,UAAU,OAAO,KAAK,EAAE;CACjkB,OAAO,oCAAoC,mBAAmB,GAAG;AACnE"}
@@ -25,7 +25,7 @@ function sanitizeDashboardCards(value) {
25
25
  id,
26
26
  title: typeof card.title === "string" && card.title.trim() ? card.title.trim() : new URL(url).hostname,
27
27
  url,
28
- size: card.size === "s" || card.size === "l" ? card.size : "m",
28
+ size: card.size === "xs" || card.size === "s" || card.size === "l" || card.size === "xl" ? card.size : "m",
29
29
  autoRefresh: card.autoRefresh === true,
30
30
  ...require_dashboard_selector.normalizeDashboardSelector(card.selector) ? { selector: require_dashboard_selector.normalizeDashboardSelector(card.selector) } : {}
31
31
  }];
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.js","names":[],"sources":["../../../../src/common/dashboard.ts"],"sourcesContent":["import { normalizeDashboardSelector } from \"./dashboard-selector\";\n\nexport type DashboardCardSize = \"s\" | \"m\" | \"l\";\n\nexport interface DashboardCard {\n id: string;\n title: string;\n url: string;\n size: DashboardCardSize;\n autoRefresh?: boolean;\n selector?: string;\n}\n\nexport function normalizeDashboardUrl(value: string): string | undefined {\n try {\n const url = new URL(value.trim());\n if ((url.protocol !== \"http:\" && url.protocol !== \"https:\") || !url.hostname) return undefined;\n return url.href;\n } catch {\n return undefined;\n }\n}\n\nexport function sanitizeDashboardCards(value: unknown): DashboardCard[] {\n if (!Array.isArray(value)) return [];\n const ids = new Set<string>();\n return value.flatMap((entry: unknown) => {\n if (!entry || typeof entry !== \"object\") return [];\n const card = entry as Partial<DashboardCard>;\n const url = typeof card.url === \"string\" ? normalizeDashboardUrl(card.url) : undefined;\n if (!url) return [];\n const preferredId = typeof card.id === \"string\" ? card.id.trim() : \"\";\n let id = preferredId || `card-${encodeURIComponent(url)}`;\n for (let suffix = 2; ids.has(id); suffix++) id = `${preferredId || `card-${encodeURIComponent(url)}`}-${suffix}`;\n ids.add(id);\n return [\n {\n id,\n title: typeof card.title === \"string\" && card.title.trim() ? card.title.trim() : new URL(url).hostname,\n url,\n size: card.size === \"s\" || card.size === \"l\" ? card.size : \"m\",\n autoRefresh: card.autoRefresh === true,\n ...(normalizeDashboardSelector(card.selector) ? { selector: normalizeDashboardSelector(card.selector) } : {}),\n } satisfies DashboardCard,\n ];\n });\n}\n"],"mappings":";;AAaA,SAAgB,sBAAsB,OAAmC;CACvE,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,MAAM,KAAK,CAAC;EAChC,IAAK,IAAI,aAAa,WAAW,IAAI,aAAa,YAAa,CAAC,IAAI,UAAU,OAAO,KAAA;EACrF,OAAO,IAAI;CACb,QAAQ;EACN;CACF;AACF;AAEA,SAAgB,uBAAuB,OAAiC;CACtE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC;CACnC,MAAM,sBAAM,IAAI,IAAY;CAC5B,OAAO,MAAM,SAAS,UAAmB;EACvC,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO,CAAC;EACjD,MAAM,OAAO;EACb,MAAM,MAAM,OAAO,KAAK,QAAQ,WAAW,sBAAsB,KAAK,GAAG,IAAI,KAAA;EAC7E,IAAI,CAAC,KAAK,OAAO,CAAC;EAClB,MAAM,cAAc,OAAO,KAAK,OAAO,WAAW,KAAK,GAAG,KAAK,IAAI;EACnE,IAAI,KAAK,eAAe,QAAQ,mBAAmB,GAAG;EACtD,KAAK,IAAI,SAAS,GAAG,IAAI,IAAI,EAAE,GAAG,UAAU,KAAK,GAAG,eAAe,QAAQ,mBAAmB,GAAG,IAAI,GAAG;EACxG,IAAI,IAAI,EAAE;EACV,OAAO,CACL;GACE;GACA,OAAO,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC;GAC9F;GACA,MAAM,KAAK,SAAS,OAAO,KAAK,SAAS,MAAM,KAAK,OAAO;GAC3D,aAAa,KAAK,gBAAgB;GAClC,GAAI,2BAAA,2BAA2B,KAAK,QAAQ,IAAI,EAAE,UAAU,2BAAA,2BAA2B,KAAK,QAAQ,EAAE,IAAI,CAAC;EAC7G,CACF;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"dashboard.js","names":[],"sources":["../../../../src/common/dashboard.ts"],"sourcesContent":["import { normalizeDashboardSelector } from \"./dashboard-selector\";\n\nexport type DashboardCardSize = \"xs\" | \"s\" | \"m\" | \"l\" | \"xl\";\n\nexport interface DashboardCard {\n id: string;\n title: string;\n url: string;\n size: DashboardCardSize;\n autoRefresh?: boolean;\n selector?: string;\n}\n\nexport function normalizeDashboardUrl(value: string): string | undefined {\n try {\n const url = new URL(value.trim());\n if ((url.protocol !== \"http:\" && url.protocol !== \"https:\") || !url.hostname) return undefined;\n return url.href;\n } catch {\n return undefined;\n }\n}\n\nexport function sanitizeDashboardCards(value: unknown): DashboardCard[] {\n if (!Array.isArray(value)) return [];\n const ids = new Set<string>();\n return value.flatMap((entry: unknown) => {\n if (!entry || typeof entry !== \"object\") return [];\n const card = entry as Partial<DashboardCard>;\n const url = typeof card.url === \"string\" ? normalizeDashboardUrl(card.url) : undefined;\n if (!url) return [];\n const preferredId = typeof card.id === \"string\" ? card.id.trim() : \"\";\n let id = preferredId || `card-${encodeURIComponent(url)}`;\n for (let suffix = 2; ids.has(id); suffix++) id = `${preferredId || `card-${encodeURIComponent(url)}`}-${suffix}`;\n ids.add(id);\n return [\n {\n id,\n title: typeof card.title === \"string\" && card.title.trim() ? card.title.trim() : new URL(url).hostname,\n url,\n size: card.size === \"xs\" || card.size === \"s\" || card.size === \"l\" || card.size === \"xl\" ? card.size : \"m\",\n autoRefresh: card.autoRefresh === true,\n ...(normalizeDashboardSelector(card.selector) ? { selector: normalizeDashboardSelector(card.selector) } : {}),\n } satisfies DashboardCard,\n ];\n });\n}\n"],"mappings":";;AAaA,SAAgB,sBAAsB,OAAmC;CACvE,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,MAAM,KAAK,CAAC;EAChC,IAAK,IAAI,aAAa,WAAW,IAAI,aAAa,YAAa,CAAC,IAAI,UAAU,OAAO,KAAA;EACrF,OAAO,IAAI;CACb,QAAQ;EACN;CACF;AACF;AAEA,SAAgB,uBAAuB,OAAiC;CACtE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC;CACnC,MAAM,sBAAM,IAAI,IAAY;CAC5B,OAAO,MAAM,SAAS,UAAmB;EACvC,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO,CAAC;EACjD,MAAM,OAAO;EACb,MAAM,MAAM,OAAO,KAAK,QAAQ,WAAW,sBAAsB,KAAK,GAAG,IAAI,KAAA;EAC7E,IAAI,CAAC,KAAK,OAAO,CAAC;EAClB,MAAM,cAAc,OAAO,KAAK,OAAO,WAAW,KAAK,GAAG,KAAK,IAAI;EACnE,IAAI,KAAK,eAAe,QAAQ,mBAAmB,GAAG;EACtD,KAAK,IAAI,SAAS,GAAG,IAAI,IAAI,EAAE,GAAG,UAAU,KAAK,GAAG,eAAe,QAAQ,mBAAmB,GAAG,IAAI,GAAG;EACxG,IAAI,IAAI,EAAE;EACV,OAAO,CACL;GACE;GACA,OAAO,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC;GAC9F;GACA,MAAM,KAAK,SAAS,QAAQ,KAAK,SAAS,OAAO,KAAK,SAAS,OAAO,KAAK,SAAS,OAAO,KAAK,OAAO;GACvG,aAAa,KAAK,gBAAgB;GAClC,GAAI,2BAAA,2BAA2B,KAAK,QAAQ,IAAI,EAAE,UAAU,2BAAA,2BAA2B,KAAK,QAAQ,EAAE,IAAI,CAAC;EAC7G,CACF;CACF,CAAC;AACH"}
@@ -0,0 +1,11 @@
1
+ //#region src/common/date-time.ts
2
+ function formatDateTime(value) {
3
+ const date = value instanceof Date ? value : new Date(value);
4
+ if (!Number.isFinite(date.getTime())) return "Unavailable";
5
+ const pad = (part) => String(part).padStart(2, "0");
6
+ return `${pad(date.getDate())}.${pad(date.getMonth() + 1)}.${String(date.getFullYear()).padStart(4, "0")} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
7
+ }
8
+ //#endregion
9
+ exports.formatDateTime = formatDateTime;
10
+
11
+ //# sourceMappingURL=date-time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-time.js","names":[],"sources":["../../../../src/common/date-time.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\nexport function formatDateTime(value: string | number | Date): string {\n const date = value instanceof Date ? value : new Date(value);\n if (!Number.isFinite(date.getTime())) return \"Unavailable\";\n const pad = (part: number) => String(part).padStart(2, \"0\");\n return `${pad(date.getDate())}.${pad(date.getMonth() + 1)}.${String(date.getFullYear()).padStart(4, \"0\")} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;\n}\n"],"mappings":";AAEA,SAAgB,eAAe,OAAuC;CACpE,MAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;CAC3D,IAAI,CAAC,OAAO,SAAS,KAAK,QAAQ,CAAC,GAAG,OAAO;CAC7C,MAAM,OAAO,SAAiB,OAAO,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;CAC1D,OAAO,GAAG,IAAI,KAAK,QAAQ,CAAC,EAAE,GAAG,IAAI,KAAK,SAAS,IAAI,CAAC,EAAE,GAAG,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,IAAI,IAAI,KAAK,SAAS,CAAC,EAAE,GAAG,IAAI,KAAK,WAAW,CAAC,EAAE,GAAG,IAAI,KAAK,WAAW,CAAC;AACtL"}
@@ -0,0 +1,17 @@
1
+ //#region src/common/monitoring-history.ts
2
+ var MONITORING_HISTORY_CHANNEL = "freelens-power:monitoring-history";
3
+ var HISTORY_MAX_BYTES = 100 * 1024 * 1024;
4
+ function validHistoryIdentity(value) {
5
+ return !!value && [value.clusterId, value.uid].every((id) => typeof id === "string" && /^[a-zA-Z0-9_.:-]{1,128}$/.test(id)) && [
6
+ "cluster",
7
+ "node",
8
+ "pod",
9
+ "workload"
10
+ ].includes(value.scope);
11
+ }
12
+ //#endregion
13
+ exports.HISTORY_MAX_BYTES = HISTORY_MAX_BYTES;
14
+ exports.MONITORING_HISTORY_CHANNEL = MONITORING_HISTORY_CHANNEL;
15
+ exports.validHistoryIdentity = validHistoryIdentity;
16
+
17
+ //# sourceMappingURL=monitoring-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitoring-history.js","names":[],"sources":["../../../../src/common/monitoring-history.ts"],"sourcesContent":["export const MONITORING_HISTORY_CHANNEL = \"freelens-power:monitoring-history\";\nexport const HISTORY_RETENTION = 7 * 24 * 60 * 60 * 1000;\nexport const HISTORY_MAX_BYTES = 100 * 1024 * 1024;\nexport type HistoryIdentity = {\n clusterId: string;\n scope: \"cluster\" | \"node\" | \"pod\" | \"workload\";\n uid: string;\n};\nexport const HISTORY_METRICS = [\n \"cpu\",\n \"memory\",\n \"cpuRequests\",\n \"memoryRequests\",\n \"cpuLimits\",\n \"memoryLimits\",\n \"cpuCapacity\",\n \"memoryCapacity\",\n \"cpuAllocatable\",\n \"memoryAllocatable\",\n \"restarts\",\n] as const;\nexport type HistoryMetric = (typeof HISTORY_METRICS)[number];\nexport type HistorySample = HistoryIdentity & { time: number; values: Partial<Record<HistoryMetric, number>> };\nexport type HistoryQuery = HistoryIdentity & { from: number; to: number };\nexport type HistoryPoint = {\n time: number;\n resolution: number;\n metric: HistoryMetric;\n min: number;\n avg: number;\n max: number;\n count: number;\n gap: boolean;\n};\nexport type HistoryStatus = { available: boolean; enabled: boolean; bytes: number; samples: number; error?: string };\nexport type HistoryRequest =\n | { operation: \"status\" | \"clear\" }\n | { operation: \"append\"; samples: HistorySample[] }\n | { operation: \"query\"; query: HistoryQuery };\nexport function validHistoryIdentity(value: HistoryIdentity): boolean {\n return (\n !!value &&\n [value.clusterId, value.uid].every((id) => typeof id === \"string\" && /^[a-zA-Z0-9_.:-]{1,128}$/.test(id)) &&\n [\"cluster\", \"node\", \"pod\", \"workload\"].includes(value.scope)\n );\n}\nexport function projectHistorySamples(input: unknown, now = Date.now()): HistorySample[] {\n if (!Array.isArray(input) || input.length > 512) throw new Error(\"Invalid history samples\");\n return input.map((sample) => {\n if (\n !validHistoryIdentity(sample) ||\n !Number.isSafeInteger(sample.time) ||\n sample.time < now - HISTORY_RETENTION ||\n sample.time > now + 30_000 ||\n !sample.values ||\n typeof sample.values !== \"object\"\n )\n throw new Error(\"Invalid history sample\");\n const values: HistorySample[\"values\"] = {};\n for (const metric of HISTORY_METRICS) {\n const value = sample.values[metric];\n if (value === undefined) continue;\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0 || value > 1e30)\n throw new Error(\"Invalid history value\");\n values[metric] = value;\n }\n return { clusterId: sample.clusterId, scope: sample.scope, uid: sample.uid, time: sample.time, values };\n });\n}\n"],"mappings":";AAAA,IAAa,6BAA6B;AAE1C,IAAa,oBAAoB,MAAM,OAAO;AAqC9C,SAAgB,qBAAqB,OAAiC;CACpE,OACE,CAAC,CAAC,SACF,CAAC,MAAM,WAAW,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,OAAO,OAAO,YAAY,2BAA2B,KAAK,EAAE,CAAC,KACxG;EAAC;EAAW;EAAQ;EAAO;CAAU,CAAC,CAAC,SAAS,MAAM,KAAK;AAE/D"}
@@ -0,0 +1,98 @@
1
+ //#region src/common/monitoring-math.ts
2
+ function effectivePodResource(pod, metric, kind) {
3
+ const read = (resources) => {
4
+ const raw = resources?.[kind]?.[metric];
5
+ if (raw !== void 0) return parseQuantity(raw, metric === "memory");
6
+ if (kind === "requests" && resources?.limits?.[metric] !== void 0) return parseQuantity(resources.limits[metric], metric === "memory");
7
+ return kind === "requests" ? 0 : Infinity;
8
+ };
9
+ const spec = pod.spec;
10
+ if (!spec?.containers?.length) throw new Error("Missing pod containers");
11
+ let sidecars = 0;
12
+ let initPeak = 0;
13
+ for (const container of spec.initContainers ?? []) {
14
+ const value = read(container.resources);
15
+ if (container.restartPolicy === "Always") {
16
+ sidecars += value;
17
+ initPeak = Math.max(initPeak, sidecars);
18
+ } else initPeak = Math.max(initPeak, sidecars + value);
19
+ }
20
+ let effective = Math.max(initPeak, sidecars + spec.containers.reduce((sum, container) => sum + read(container.resources), 0));
21
+ if (spec.resources?.[kind]?.[metric] !== void 0) effective = read(spec.resources);
22
+ const overhead = spec.overhead?.[metric];
23
+ if (overhead !== void 0 && (kind === "requests" || effective > 0)) effective += parseQuantity(overhead, metric === "memory");
24
+ return effective;
25
+ }
26
+ function aggregateResources(nodes, pods) {
27
+ if (!nodes.length || nodes.some((node) => !node.metadata?.name)) throw new Error("Missing node inventory");
28
+ const names = new Set(nodes.map((node) => node.metadata.name));
29
+ const scheduled = pods?.filter((pod) => pod.spec?.nodeName && names.has(pod.spec.nodeName) && pod.status?.phase !== "Succeeded" && pod.status?.phase !== "Failed");
30
+ const sum = (metric) => {
31
+ const capacity = nodes.reduce((total, node) => total + parseQuantity(node.status?.capacity?.[metric] ?? "", metric === "memory"), 0);
32
+ const allocatable = nodes.reduce((total, node) => total + parseQuantity(node.status?.allocatable?.[metric] ?? "", metric === "memory"), 0);
33
+ const requests = scheduled?.reduce((total, pod) => total + effectivePodResource(pod, metric, "requests"), 0);
34
+ const limits = scheduled?.reduce((total, pod) => total + effectivePodResource(pod, metric, "limits"), 0);
35
+ return {
36
+ capacity,
37
+ allocatable,
38
+ requests,
39
+ limits: limits === Infinity ? void 0 : limits,
40
+ unbounded: limits === Infinity
41
+ };
42
+ };
43
+ return {
44
+ cpu: sum("cpu"),
45
+ memory: sum("memory")
46
+ };
47
+ }
48
+ var MONITORING_INTERVAL = 3e4;
49
+ function parseQuantity(raw, memory = false) {
50
+ const match = /^(\d+(?:\.\d*)?|\.\d+)([eE][+-]?\d+|n|u|m|Ki|Mi|Gi|Ti|Pi|Ei|k|K|M|G|T|P|E)?$/.exec(raw);
51
+ if (!match) throw new Error("Invalid metrics quantity");
52
+ const suffix = match[2] ?? "";
53
+ const value = Number(match[1]) * (suffix.endsWith("i") ? 1024 ** ([
54
+ "Ki",
55
+ "Mi",
56
+ "Gi",
57
+ "Ti",
58
+ "Pi",
59
+ "Ei"
60
+ ].indexOf(suffix) + 1) : /^[eE][+-]?\d+$/.test(suffix) ? 10 ** Number(suffix.slice(1)) : {
61
+ n: 1e-9,
62
+ u: 1e-6,
63
+ m: .001,
64
+ k: 1e3,
65
+ K: 1e3,
66
+ M: 1e6,
67
+ G: 1e9,
68
+ T: 0xe8d4a51000,
69
+ P: 0x38d7ea4c68000,
70
+ E: 0xde0b6b3a7640000
71
+ }[suffix] ?? 1);
72
+ if (!Number.isFinite(value) || !memory && suffix.endsWith("i")) throw new Error("Invalid metrics quantity");
73
+ return value;
74
+ }
75
+ function aggregateMetrics(nodes, now = Date.now()) {
76
+ if (!nodes.length) throw new Error("No node metrics available");
77
+ let cpu = 0;
78
+ let memory = 0;
79
+ for (const node of nodes) {
80
+ const timestamp = Date.parse(node.timestamp);
81
+ if (!Number.isFinite(timestamp) || now - timestamp > 12e4 || timestamp > now + 3e4) throw new Error("Node metrics are stale");
82
+ cpu += parseQuantity(node.usage.cpu);
83
+ memory += parseQuantity(node.usage.memory, true);
84
+ }
85
+ return {
86
+ time: now,
87
+ cpu,
88
+ memory
89
+ };
90
+ }
91
+ //#endregion
92
+ exports.MONITORING_INTERVAL = MONITORING_INTERVAL;
93
+ exports.aggregateMetrics = aggregateMetrics;
94
+ exports.aggregateResources = aggregateResources;
95
+ exports.effectivePodResource = effectivePodResource;
96
+ exports.parseQuantity = parseQuantity;
97
+
98
+ //# sourceMappingURL=monitoring-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitoring-math.js","names":[],"sources":["../../../../src/common/monitoring-math.ts"],"sourcesContent":["type ResourceValues = { requests?: Partial<Record<string, string>>; limits?: Partial<Record<string, string>> };\ntype ResourceContainer = { resources?: ResourceValues; restartPolicy?: string };\nexport type MonitoringPod = {\n spec?: {\n nodeName?: string;\n containers?: ResourceContainer[];\n initContainers?: ResourceContainer[];\n overhead?: Partial<Record<string, string>>;\n resources?: ResourceValues;\n };\n status?: { phase?: string };\n};\nexport type MonitoringNode = {\n metadata: { name: string };\n status?: { capacity?: Partial<Record<string, string>>; allocatable?: Partial<Record<string, string>> };\n};\ntype ResourceTotals = {\n capacity?: number;\n allocatable?: number;\n requests?: number;\n limits?: number;\n unbounded?: boolean;\n};\nexport type MonitoringSample = {\n time: number;\n cpu: number;\n memory: number;\n resources?: Record<\"cpu\" | \"memory\", ResourceTotals>;\n resourceStatus?: string;\n completeUsage?: boolean;\n breakBefore?: boolean;\n historical?: Partial<\n Record<\"cpu\" | \"memory\", { min: number; max: number; count: number; resolution: number; gap: boolean }>\n >;\n};\n\nexport function effectivePodResource(\n pod: MonitoringPod,\n metric: \"cpu\" | \"memory\",\n kind: \"requests\" | \"limits\",\n): number {\n const read = (resources?: ResourceValues) => {\n const raw = resources?.[kind]?.[metric];\n if (raw !== undefined) return parseQuantity(raw, metric === \"memory\");\n if (kind === \"requests\" && resources?.limits?.[metric] !== undefined)\n return parseQuantity(resources.limits[metric], metric === \"memory\");\n return kind === \"requests\" ? 0 : Infinity;\n };\n const spec = pod.spec;\n if (!spec?.containers?.length) throw new Error(\"Missing pod containers\");\n let sidecars = 0;\n let initPeak = 0;\n for (const container of spec.initContainers ?? []) {\n const value = read(container.resources);\n if (container.restartPolicy === \"Always\") {\n sidecars += value;\n initPeak = Math.max(initPeak, sidecars);\n } else initPeak = Math.max(initPeak, sidecars + value);\n }\n let effective = Math.max(\n initPeak,\n sidecars + spec.containers.reduce((sum, container) => sum + read(container.resources), 0),\n );\n if (spec.resources?.[kind]?.[metric] !== undefined) effective = read(spec.resources);\n const overhead = spec.overhead?.[metric];\n if (overhead !== undefined && (kind === \"requests\" || effective > 0))\n effective += parseQuantity(overhead, metric === \"memory\");\n return effective;\n}\n\nexport function aggregateResources(\n nodes: MonitoringNode[],\n pods?: MonitoringPod[],\n): Record<\"cpu\" | \"memory\", ResourceTotals> {\n if (!nodes.length || nodes.some((node) => !node.metadata?.name)) throw new Error(\"Missing node inventory\");\n const names = new Set(nodes.map((node) => node.metadata.name));\n const scheduled = pods?.filter(\n (pod) =>\n pod.spec?.nodeName &&\n names.has(pod.spec.nodeName) &&\n pod.status?.phase !== \"Succeeded\" &&\n pod.status?.phase !== \"Failed\",\n );\n const sum = (metric: \"cpu\" | \"memory\"): ResourceTotals => {\n const capacity = nodes.reduce(\n (total, node) => total + parseQuantity(node.status?.capacity?.[metric] ?? \"\", metric === \"memory\"),\n 0,\n );\n const allocatable = nodes.reduce(\n (total, node) => total + parseQuantity(node.status?.allocatable?.[metric] ?? \"\", metric === \"memory\"),\n 0,\n );\n const requests = scheduled?.reduce((total, pod) => total + effectivePodResource(pod, metric, \"requests\"), 0);\n const limits = scheduled?.reduce((total, pod) => total + effectivePodResource(pod, metric, \"limits\"), 0);\n return {\n capacity,\n allocatable,\n requests,\n limits: limits === Infinity ? undefined : limits,\n unbounded: limits === Infinity,\n };\n };\n return { cpu: sum(\"cpu\"), memory: sum(\"memory\") };\n}\nexport const MONITORING_INTERVAL = 30_000;\nexport const MAX_SAMPLES = 60;\n\nexport function parseQuantity(raw: string, memory = false): number {\n const match = /^(\\d+(?:\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+|n|u|m|Ki|Mi|Gi|Ti|Pi|Ei|k|K|M|G|T|P|E)?$/.exec(raw);\n if (!match) throw new Error(\"Invalid metrics quantity\");\n const suffix = match[2] ?? \"\";\n const factors: Record<string, number> = {\n n: 1e-9,\n u: 1e-6,\n m: 1e-3,\n k: 1e3,\n K: 1e3,\n M: 1e6,\n G: 1e9,\n T: 1e12,\n P: 1e15,\n E: 1e18,\n };\n const value =\n Number(match[1]) *\n (suffix.endsWith(\"i\")\n ? 1024 ** ([\"Ki\", \"Mi\", \"Gi\", \"Ti\", \"Pi\", \"Ei\"].indexOf(suffix) + 1)\n : /^[eE][+-]?\\d+$/.test(suffix)\n ? 10 ** Number(suffix.slice(1))\n : (factors[suffix] ?? 1));\n if (!Number.isFinite(value) || (!memory && suffix.endsWith(\"i\"))) throw new Error(\"Invalid metrics quantity\");\n return value;\n}\n\nexport function aggregateMetrics(\n nodes: { usage: { cpu: string; memory: string }; timestamp: string }[],\n now = Date.now(),\n): MonitoringSample {\n if (!nodes.length) throw new Error(\"No node metrics available\");\n let cpu = 0;\n let memory = 0;\n for (const node of nodes) {\n const timestamp = Date.parse(node.timestamp);\n if (!Number.isFinite(timestamp) || now - timestamp > 120_000 || timestamp > now + 30_000)\n throw new Error(\"Node metrics are stale\");\n cpu += parseQuantity(node.usage.cpu);\n memory += parseQuantity(node.usage.memory, true);\n }\n return { time: now, cpu, memory };\n}\n"],"mappings":"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"}