@64mb/freelens-power 1.1.0 → 1.2.1
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.
- package/README.md +5 -4
- package/THIRD_PARTY_LICENSES +1707 -0
- package/out/main/ai.js +63 -23
- package/out/main/ai.js.map +1 -1
- package/out/main/cluster-icons-catalog.js +28 -0
- package/out/main/cluster-icons-catalog.js.map +1 -0
- package/out/main/cluster-icons.js +125 -0
- package/out/main/cluster-icons.js.map +1 -0
- package/out/main/common/ai-terminal-context.js +51 -0
- package/out/main/common/ai-terminal-context.js.map +1 -0
- package/out/main/common/ai.js.map +1 -1
- package/out/main/common/cluster-icon-ipc.js +6 -0
- package/out/main/common/cluster-icon-ipc.js.map +1 -0
- package/out/main/common/cluster-icons.js +121 -0
- package/out/main/common/cluster-icons.js.map +1 -0
- package/out/main/common/dashboard.js +2 -1
- package/out/main/common/dashboard.js.map +1 -1
- package/out/main/common/settings-export.js +4 -2
- package/out/main/common/settings-export.js.map +1 -1
- package/out/main/common/store/cluster-icons-store.js +32 -0
- package/out/main/common/store/cluster-icons-store.js.map +1 -0
- package/out/main/common/store/dashboard-preferences-store.js +2 -1
- package/out/main/common/store/dashboard-preferences-store.js.map +1 -1
- package/out/main/common/store/monitoring-preferences-store.js +5 -0
- package/out/main/common/store/monitoring-preferences-store.js.map +1 -1
- package/out/main/dashboard-views.js +20 -10
- package/out/main/dashboard-views.js.map +1 -1
- package/out/main/diagnostics-menu-order.js +57 -0
- package/out/main/diagnostics-menu-order.js.map +1 -0
- package/out/main/index.js +9 -1
- package/out/main/index.js.map +1 -1
- package/out/main/monitoring-history.js +13 -3
- package/out/main/monitoring-history.js.map +1 -1
- package/out/renderer/_virtual/_global-external_react-dom.js +2 -1
- package/out/renderer/_virtual/_global-external_react.js +10 -5
- package/out/renderer/_virtual/_rolldown/runtime.js +22 -0
- package/out/renderer/ai-terminal-context.js +200 -0
- package/out/renderer/ai-terminal-context.js.map +1 -0
- package/out/renderer/ai.js +90 -9
- package/out/renderer/ai.js.map +1 -1
- package/out/renderer/appearance.js +1 -0
- package/out/renderer/appearance.js.map +1 -1
- package/out/renderer/cluster-icon-colors.js +188 -0
- package/out/renderer/cluster-icon-colors.js.map +1 -0
- package/out/renderer/cluster-icons.js +304 -0
- package/out/renderer/cluster-icons.js.map +1 -0
- package/out/renderer/dashboard.js +51 -14
- package/out/renderer/dashboard.js.map +1 -1
- package/out/renderer/details/secret-certificate-details.js +9 -2
- package/out/renderer/details/secret-certificate-details.js.map +1 -1
- package/out/renderer/diagnostics.css.js +39 -0
- package/out/renderer/diagnostics.css.js.map +1 -0
- package/out/renderer/diagnostics.js +796 -343
- package/out/renderer/diagnostics.js.map +1 -1
- package/out/renderer/index.js +9 -4
- package/out/renderer/index.js.map +1 -1
- package/out/renderer/monitoring-details-chart.js +42 -0
- package/out/renderer/monitoring-details-chart.js.map +1 -0
- package/out/renderer/monitoring-history-collection.js +2 -18
- package/out/renderer/monitoring-history-collection.js.map +1 -1
- package/out/renderer/monitoring-history-view.js +111 -34
- package/out/renderer/monitoring-history-view.js.map +1 -1
- package/out/renderer/monitoring.js +68 -27
- package/out/renderer/monitoring.js.map +1 -1
- package/out/renderer/node-monitoring.js +23 -12
- package/out/renderer/node-monitoring.js.map +1 -1
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js +10 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js +8 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js +9 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js +9 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/classCallCheck.js +8 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/classCallCheck.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createClass.js +15 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createClass.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createSuper.js +19 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createSuper.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/defineProperty.js +14 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/defineProperty.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js +19 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js +15 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inherits.js +14 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inherits.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js +18 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArray.js +8 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArray.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js +26 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js +8 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js +8 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectSpread2.js +27 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectSpread2.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js +15 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +14 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js +12 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js +15 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/slicedToArray.js +12 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/slicedToArray.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js +8 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js +12 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPrimitive.js +16 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPrimitive.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js +11 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/typeof.js +18 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/typeof.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js +13 -0
- package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js +237 -0
- package/out/renderer/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js +25 -0
- package/out/renderer/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js +12 -0
- package/out/renderer/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js.map +1 -0
- 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
- 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
- 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
- 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
- package/out/renderer/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js +133 -0
- package/out/renderer/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js +65 -0
- package/out/renderer/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js +54 -0
- package/out/renderer/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js.map +1 -0
- 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
- 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
- package/out/renderer/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js +30 -0
- package/out/renderer/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/@floating-ui_dom@1.7.2/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +211 -0
- 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
- 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
- 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
- package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +31 -0
- 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
- 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
- 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
- package/out/renderer/node_modules/.pnpm/memoize-one@6.0.0/node_modules/memoize-one/dist/memoize-one.esm.js +38 -0
- package/out/renderer/node_modules/.pnpm/memoize-one@6.0.0/node_modules/memoize-one/dist/memoize-one.esm.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js +159 -0
- package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js +103 -0
- package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js +18 -0
- package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js.map +1 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js +22 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js +30 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js +164 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js +37 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js +245 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js.map +1 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js +120 -0
- package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js.map +1 -0
- 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
- 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
- package/out/renderer/pod-monitoring.js +15 -19
- package/out/renderer/pod-monitoring.js.map +1 -1
- package/out/renderer/preferences/ai-shortcuts-preferences.js +12 -4
- package/out/renderer/preferences/ai-shortcuts-preferences.js.map +1 -1
- package/out/renderer/preferences/dashboard-preferences.js +37 -6
- package/out/renderer/preferences/dashboard-preferences.js.map +1 -1
- package/out/renderer/preferences/monitoring-preferences.js +131 -44
- package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
- package/out/renderer/preferences/preferences.js +31 -7
- package/out/renderer/preferences/preferences.js.map +1 -1
- package/out/renderer/read-only.js +2 -2
- package/out/renderer/read-only.js.map +1 -1
- package/out/renderer/src/common/ai-terminal-context.js +51 -0
- package/out/renderer/src/common/ai-terminal-context.js.map +1 -0
- package/out/renderer/src/common/ai.js.map +1 -1
- package/out/renderer/src/common/cluster-icon-ipc.js +6 -0
- package/out/renderer/src/common/cluster-icon-ipc.js.map +1 -0
- package/out/renderer/src/common/cluster-icons.js +133 -0
- package/out/renderer/src/common/cluster-icons.js.map +1 -0
- package/out/renderer/src/common/dashboard.js +2 -1
- package/out/renderer/src/common/dashboard.js.map +1 -1
- package/out/renderer/src/common/date-time.js +11 -0
- package/out/renderer/src/common/date-time.js.map +1 -0
- package/out/renderer/src/common/monitoring-history.js +2 -0
- package/out/renderer/src/common/monitoring-history.js.map +1 -1
- package/out/renderer/src/common/resource-diagnostics.js.map +1 -1
- package/out/renderer/src/common/settings-export.js.map +1 -1
- package/out/renderer/src/common/store/dashboard-preferences-store.js +2 -1
- package/out/renderer/src/common/store/dashboard-preferences-store.js.map +1 -1
- package/out/renderer/src/common/store/monitoring-preferences-store.js +5 -0
- package/out/renderer/src/common/store/monitoring-preferences-store.js.map +1 -1
- package/out/renderer/welcome.js +28 -6
- package/out/renderer/welcome.js.map +1 -1
- package/package.json +3 -2
package/out/renderer/ai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.js","names":[],"sources":["../../src/renderer/ai.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { ipcRenderer } from \"electron\";\nimport { autorun } from \"mobx\";\nimport { observer } from \"mobx-react\";\nimport { type CSSProperties, useEffect, useRef, useState } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { AI_CHAT_CHANNEL, AI_READ_ACTIVITY_CHANNEL, type AiReadActivity } from \"../common/ai\";\nimport { AI_CANCEL_CHANNEL, attachedAiContext, normalizeAiReferences } from \"../common/ai-extras\";\nimport { expandAiShortcut } from \"../common/ai-shortcuts\";\nimport { type AiMessage, AiPreferencesStore } from \"../common/store/ai-preferences-store\";\nimport { AiShortcutsStore } from \"../common/store/ai-shortcuts-store\";\nimport { AiCopyAnswer } from \"./ai-copy-answer\";\nimport { AiContextPreview, AiResourceReferences } from \"./ai-extras\";\nimport { AiIcon } from \"./ai-icon\";\nimport { AiMessageContent } from \"./ai-message\";\nimport { AiProviderIcon } from \"./ai-provider-icon\";\nimport { AiResizeHandle, clampAiPanelWidth, DEFAULT_AI_PANEL_WIDTH } from \"./ai-resize\";\nimport { AiStarterPrompts } from \"./ai-shortcuts\";\n\nexport interface AiScreenContext {\n clusterId?: string;\n screen?: string;\n resource?: { kind?: string; namespace?: string; name?: string };\n}\n\nexport function readAiContext(): AiScreenContext {\n const clusterId = Renderer.Catalog.activeCluster.get()?.metadata.uid;\n const screen = window.location.pathname;\n const details = new URLSearchParams(window.location.search).get(\"kube-details\");\n const match =\n details?.match(/^\\/api(?:\\/v\\d+)?\\/namespaces\\/([^/]+)\\/([^/]+)\\/([^/]+)$/) ??\n details?.match(/^\\/apis\\/[^/]+\\/[^/]+\\/namespaces\\/([^/]+)\\/([^/]+)\\/([^/]+)$/);\n const clusterResource =\n details?.match(/^\\/api\\/[^/]+\\/([^/]+)\\/([^/]+)$/) ?? details?.match(/^\\/apis\\/[^/]+\\/[^/]+\\/([^/]+)\\/([^/]+)$/);\n const resource = match\n ? { namespace: match[1], kind: match[2], name: match[3] }\n : clusterResource\n ? { kind: clusterResource[1], name: clusterResource[2] }\n : undefined;\n return { clusterId, screen, ...(resource ? { resource } : {}) };\n}\n\nexport function isAiClusterDocument(): boolean {\n return window.top !== window && Boolean(Renderer.Catalog.activeCluster.get());\n}\n\nexport function aiLauncherBottom(): number {\n const dock = document.querySelector<HTMLElement>(\".Dock\");\n if (!dock) return 16;\n const rect = dock.getBoundingClientRect();\n const style = window.getComputedStyle(dock);\n if (\n dock.hidden ||\n style.display === \"none\" ||\n style.visibility === \"hidden\" ||\n rect.width <= 0 ||\n rect.height <= 0 ||\n rect.top <= 0 ||\n rect.top >= window.innerHeight\n )\n return 16;\n return Math.max(16, window.innerHeight - rect.top + 16);\n}\n\nexport function aiLauncherLeft(): number {\n const sidebar = document.querySelector<HTMLElement>('[data-testid=\"cluster-sidebar\"], .Sidebar');\n const dock = document.querySelector<HTMLElement>(\".Dock\");\n let contentLeft = 0;\n for (const [element, edge] of [\n [sidebar, \"right\"],\n [dock, \"left\"],\n ] as const) {\n if (!element || element.hidden) continue;\n const style = window.getComputedStyle(element);\n const rect = element.getBoundingClientRect();\n if (style.display === \"none\" || style.visibility === \"hidden\" || rect.width <= 0) continue;\n const value = rect[edge];\n if (Number.isFinite(value) && value >= 0 && value < window.innerWidth - 80)\n contentLeft = Math.max(contentLeft, value);\n }\n return contentLeft + 16;\n}\n\nexport function hasAiResourceDetails(): boolean {\n if (new URLSearchParams(window.location.search).get(\"kube-details\")) return true;\n return Array.from(\n document.querySelectorAll<HTMLElement>(\".Drawer.KubeObjectDetails, .Drawer.ReleaseDetails, .DetailsDrawer\"),\n ).some((element) => {\n const style = window.getComputedStyle(element);\n const rect = element.getBoundingClientRect();\n return (\n !element.hidden && style.display !== \"none\" && style.visibility !== \"hidden\" && rect.width > 0 && rect.height > 0\n );\n });\n}\n\nexport function hasAiOverlay(): boolean {\n return Array.from(document.querySelectorAll<HTMLElement>('[role=\"dialog\"], dialog[open], .Dialog')).some(\n (element) => {\n const style = window.getComputedStyle(element);\n return !element.hidden && style.display !== \"none\" && style.visibility !== \"hidden\";\n },\n );\n}\n\nconst styles = `\n@keyframes power-ai-spin { to { transform: rotate(360deg); } }\n@keyframes power-ai-dot { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }\n.power-ai-read-activity > span { display: inline-flex; align-items: center; gap: 4px; }\n.power-ai-read-activity [data-status=\"reading\"] .Icon { animation: power-ai-spin 1.2s linear infinite; }\n.power-ai-thinking { margin: 12px 16px 18px; line-height: 1.5; color: var(--textColorSecondary); }\n.power-ai-dots > span { animation: power-ai-dot 1.3s ease-in-out infinite; }\n.power-ai-dots > span:nth-child(2) { animation-delay: .15s; }\n.power-ai-dots > span:nth-child(3) { animation-delay: .3s; }\n@media (prefers-reduced-motion: reduce) { .power-ai-read-activity [data-status=\"reading\"] .Icon, .power-ai-dots > span { animation: none; } }\n@keyframes power-ai-enter { from { transform: translateX(100%); } to { transform: translateX(0); } }\n:root .power-ai-launcher { position: fixed; bottom: 16px; left: auto; right: 16px; z-index: 100; display: inline-flex; align-items: center; gap: 6px; min-width: 0; min-height: 0; height: 34px; border: 1px solid var(--primary, #5896ff); border-radius: 24px; padding: 0 13px; background: var(--contentColor, #242424); color: var(--textColorAccent); box-shadow: 0 3px 12px #0003; font: inherit; font-size: 12px; font-weight: 500; line-height: 1; cursor: pointer; transition: opacity 180ms ease, background-color 140ms ease, box-shadow 140ms ease, transform 180ms ease; }\n.power-ai-overview-actions { position: relative; z-index: 5; height: 0; min-height: 0; flex: 0 0 0; pointer-events: none; }\n.power-ai-overview-actions + [data-testid=\"cluster-overview-page\"] [data-monitoring-summaries] { --power-monitoring-summary-top: 56px; }\n.power-ai-overview-actions button { transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease, box-shadow 160ms ease; position: absolute; top: 12px; right: 12px; pointer-events: auto; box-shadow: 0 2px 8px #0002; display: inline-flex; flex: 0 0 auto; width: auto; align-items: center; gap: 6px; min-height: 32px; padding: 6px 12px; font: inherit; font-size: 12px; border: 1px solid var(--borderFaintColor); border-radius: 10px; color: var(--textColorPrimary); background: var(--contentColor); cursor: pointer; }\n.power-ai-overview-actions button:hover { border-color: var(--primary); color: var(--textColorAccent); background: var(--contentColor); }\n.power-ai-overview-actions button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n.power-ai-launcher.power-ai-launcher-hidden { opacity: 0; transform: translateY(8px); pointer-events: none; }\n.power-ai-launcher .Icon { color: inherit; }\n.power-ai-launcher:hover { background: color-mix(in srgb, var(--primary, #5896ff) 12%, var(--contentColor, #242424)); box-shadow: 0 4px 12px #0003; transform: translateY(-1px); }\n.power-ai-launcher:active { transform: translateY(0); box-shadow: 0 2px 6px #0002; }\n@media (prefers-reduced-motion: reduce) { :root .power-ai-launcher { transition: none; } .power-ai-launcher:hover, .power-ai-launcher:active { transform: none; } }\n.power-ai-launcher:focus-visible { outline: 2px solid var(--primary, #5896ff); outline-offset: 3px; }\n.power-ai-panel { position: fixed; right: 0; top: 0; bottom: 0; width: min(560px, 100vw); z-index: 10001; display: flex; flex-direction: column; background: var(--contentColor, #242424); color: var(--textColorAccent, white); animation: power-ai-enter 160ms ease-out; border-left: 1px solid var(--borderFaintColor); box-shadow: -4px 0 24px #0004; }\n.power-ai-resize-handle { position: absolute; left: -4px; top: 0; bottom: 0; width: 8px; z-index: 2; cursor: col-resize; touch-action: none; }\n.power-ai-resize-handle:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }\n.power-ai-panel header { padding: 16px; display: flex; gap: 10px; flex-shrink: 0; }\n.power-ai-panel header { border-bottom: 1px solid var(--borderFaintColor); justify-content: space-between; align-items: center; }\n.power-ai-messages { overflow: auto; flex: 1; min-height: 0; padding: 24px 16px; font-size: var(--power-ai-font-size, 14px); line-height: 1.65; overscroll-behavior: contain; }\n.power-ai-message { overflow-wrap: anywhere; padding: 14px 16px; margin-bottom: 20px; color: var(--textColorAccent); border: 1px solid var(--borderFaintColor); border-radius: 8px; }\n.power-ai-panel button { padding: 7px 10px; border: 1px solid var(--borderFaintColor); border-radius: 8px; background: var(--contentColor); color: var(--textColorPrimary); cursor: pointer; }\n:root .power-ai-panel header button:is(.power-ai-close, .power-ai-pin) { width: 30px; height: 30px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); }\n:root .power-ai-panel header button:is(.power-ai-close, .power-ai-pin):not(:disabled):not(.disabled):hover { color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }\n:root .power-ai-panel header button:is(.power-ai-close, .power-ai-pin):focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n:root .power-ai-panel button.power-ai-copy-answer { width: 24px; height: 24px; padding: 0; margin-left: auto; flex-shrink: 0; justify-content: center; border: 0; background: transparent; color: var(--textColorSecondary); }\n:root .power-ai-panel button.power-ai-copy-answer:not(:disabled):not(.disabled):hover { color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }\n:root .power-ai-panel button.power-ai-copy-answer:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n.power-ai-cancellation { display: flex; align-items: center; gap: 6px; }\n:root .power-ai-panel button.power-ai-dismiss { width: 24px; height: 24px; padding: 0; justify-content: center; border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); }\n:root .power-ai-panel button.power-ai-dismiss:hover { color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }\n:root .power-ai-panel button.power-ai-dismiss:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n.power-ai-panel button:disabled { opacity: 0.5; cursor: default; }\n .power-ai-panel textarea { display: block; width: 100%; box-sizing: border-box; min-width: 0; min-height: 64px; max-height: 180px; field-sizing: content; padding: 12px 16px 6px; border: 0; border-radius: 12px; background: transparent; color: var(--textColorAccent); font: inherit; font-size: var(--power-ai-font-size, 14px); line-height: 1.5; resize: none; }\n.power-ai-panel textarea::placeholder { color: var(--textColorSecondary); opacity: 1; }\n.power-ai-panel textarea:focus { outline: none; }\n.power-ai-composer-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 10px 10px 16px; }\n.power-ai-composer-footer > span { color: var(--textColorSecondary); font-size: 11px; line-height: 1.5; }\n:root .power-ai-panel form button[type=\"submit\"] { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 34px; width: 34px; height: 34px; padding: 0; border-radius: 10px; }\n:root .power-ai-panel form button[type=\"submit\"]:not(:disabled):not(.disabled) { background-color: var(--primary); border-color: var(--primary); color: white; }\n:root .power-ai-panel form button[type=\"submit\"]:not(:disabled):not(.disabled):hover { background-color: color-mix(in srgb, var(--primary) 88%, white 12%); border-color: color-mix(in srgb, var(--primary) 88%, white 12%); color: white; }\n:root .power-ai-panel form button[type=\"submit\"]:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }\n:root .power-ai-panel form button[type=\"submit\"]:disabled { background-color: var(--contentColor); border-color: var(--borderFaintColor); color: var(--textColorSecondary); }\n.power-ai-message-user { border-color: color-mix(in srgb, var(--primary) 28%, var(--borderFaintColor)); background: color-mix(in srgb, var(--primary) 7%, var(--mainBackground)); }\n.power-ai-context { padding: 10px 20px; line-height: 1.5; border-bottom: 1px solid var(--borderFaintColor); font-size: 12px; color: var(--textColorSecondary); overflow-wrap: anywhere; }\n.power-ai-title, .power-ai-panel button { display: inline-flex; align-items: center; gap: 6px; }\n.power-ai-title { margin-right: auto; white-space: nowrap; color: var(--textColorAccent); }\n.power-ai-brand { display: inline-flex; align-items: center; gap: 6px; color: var(--primary); }\n.power-ai-brand .Icon { color: inherit; }\n:root .power-ai-panel header button.power-ai-pin[aria-pressed=\"true\"] { color: var(--primary); }\n.power-ai-panel header > button { flex-shrink: 0; }\n.power-ai-panel form { position: relative; flex-shrink: 0; margin: 0 16px 16px; border: 1px solid var(--borderFaintColor); border-radius: 12px; background: var(--mainBackground); transition: border-color 160ms ease; }\n.power-ai-panel form:focus-within { border-color: var(--primary); }\n.power-ai-message > strong { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 500; color: var(--textColorSecondary); margin-bottom: 10px; }\n.power-ai-message-assistant { border-color: transparent; background: transparent; }\n.power-ai-markdown { line-height: 1.65; font-size: var(--power-ai-font-size, 14px); color: var(--textColorAccent); }\n.power-ai-markdown p { margin: 0 0 14px; white-space: pre-wrap; }\n.power-ai-markdown p:last-child { margin-bottom: 0; }\n.power-ai-markdown ul, .power-ai-markdown ol { padding-left: 24px; margin: 10px 0 16px; }\n.power-ai-markdown ul { list-style: disc; }\n.power-ai-markdown ol { list-style: decimal; }\n.power-ai-markdown li { margin: 5px 0; }\n.power-ai-markdown li > ul, .power-ai-markdown li > ol { margin: 6px 0; }\n.power-ai-markdown li > p { margin-bottom: 6px; }\n.power-ai-markdown :is(h1, h2, h3, h4, h5, h6) { color: var(--textColorAccent); font-weight: 600; line-height: 1.4; margin: 24px 0 12px; }\n.power-ai-markdown :is(h1, h2, h3, h4, h5, h6):first-child { margin-top: 0; }\n.power-ai-markdown h1 { font-size: 1.43em; }\n.power-ai-markdown h2 { font-size: 1.29em; }\n.power-ai-markdown h3 { font-size: 1.14em; }\n.power-ai-markdown :is(h4, h5, h6) { font-size: 1em; }\n.power-ai-markdown blockquote { margin: 16px 0; padding: 4px 14px; border-left: 3px solid var(--borderColor); color: var(--textColorSecondary); }\n.power-ai-markdown blockquote > p:last-child { margin-bottom: 0; }\n.power-ai-markdown table { display: block; max-width: 100%; overflow-x: auto; margin: 16px 0; border-collapse: collapse; font-size: max(10px, calc(var(--power-ai-font-size, 14px) - 1px)); }\n.power-ai-markdown th, .power-ai-markdown td { padding: 9px 12px; border: 1px solid var(--borderFaintColor); text-align: left; }\n.power-ai-markdown th { font-weight: 600; background: color-mix(in srgb, var(--textColorAccent) 5%, transparent); }\n.power-ai-markdown a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }\n.power-ai-markdown hr { margin: 20px 0; border: 0; border-top: 1px solid var(--borderFaintColor); }\n.power-ai-markdown code { font-family: var(--font-monospace, monospace); font-size: max(10px, calc(var(--power-ai-font-size, 14px) - 1px)); background: color-mix(in srgb, var(--textColorAccent) 8%, transparent); padding: 1px 4px; border-radius: 4px; }\n.power-ai-code { margin: 12px 0; border: 1px solid var(--borderFaintColor); border-radius: 8px; overflow: hidden; background: var(--mainBackground); }\n.power-ai-code-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 8px; border-bottom: 1px solid var(--borderFaintColor); color: var(--textColorSecondary); font-size: 11px; }\n.power-ai-code-toolbar > div { display: flex; gap: 4px; }\n.power-ai-code-toolbar button { padding: 4px 6px; font-size: 11px; }\n.power-ai-code pre { margin: 0; padding: 12px; overflow-x: auto; white-space: pre; }\n.power-ai-code pre code { padding: 0; background: transparent; }\n.power-ai-code-hint, .power-ai-code-feedback:not(:empty) { padding: 0 12px 10px; color: var(--textColorSecondary); font-size: 11px; }\n.power-ai-autocomplete { position: absolute; bottom: calc(100% + 8px); left: 0; right: 0; max-height: 240px; overflow-y: auto; padding: 6px; border: 1px solid var(--borderColor); border-radius: 10px; background: var(--contentColor); box-shadow: 0 4px 16px #0003; }\n.power-ai-autocomplete button { display: flex; width: 100%; justify-content: space-between; gap: 12px; border: 0; text-align: left; }\n.power-ai-autocomplete button[aria-selected=\"true\"] { background: color-mix(in srgb, var(--primary) 14%, var(--contentColor)); color: var(--textColorAccent); }\n.power-ai-autocomplete button > span:last-child { color: var(--textColorSecondary); font-size: 12px; }\n@media (prefers-reduced-motion: reduce) { .power-ai-panel { animation: none; } }\n`;\n\nconst AiChat = observer(({ isClusterDocument }: { isClusterDocument: () => boolean }) => {\n const preferences = AiPreferencesStore.getInstanceOrCreate<AiPreferencesStore>();\n const [open, setOpen] = useState(false);\n const [pinned, setPinned] = useState(false);\n const [launcherBottom, setLauncherBottom] = useState(aiLauncherBottom);\n const [launcherLeft, setLauncherLeft] = useState(aiLauncherLeft);\n const [resourceDetailsOpen, setResourceDetailsOpen] = useState(hasAiResourceDetails);\n const [viewportWidth, setViewportWidth] = useState(window.innerWidth);\n const [launcherHidden, setLauncherHidden] = useState(false);\n const [draft, setDraft] = useState(\"\");\n const [suggestionIndex, setSuggestionIndex] = useState(0);\n const [dismissedDraft, setDismissedDraft] = useState<string>();\n const suggestions =\n /^\\/[^\\s]*$/.test(draft) && dismissedDraft !== draft\n ? AiShortcutsStore.getInstanceOrCreate<AiShortcutsStore>().shortcuts.filter((shortcut) =>\n `${shortcut.command} ${shortcut.label}`.toLowerCase().includes(draft.slice(1).toLowerCase()),\n )\n : [];\n const dismissSuggestions = useRef<() => boolean>(() => false);\n dismissSuggestions.current = () => {\n if (!suggestions.length) return false;\n setDismissedDraft(draft);\n return true;\n };\n const following = useRef(true);\n const composer = useRef<HTMLTextAreaElement>(null);\n const selectSuggestion = (index: number) => {\n const shortcut = suggestions[index];\n if (!shortcut) return;\n setDraft(`/${shortcut.command} `);\n setSuggestionIndex(0);\n composer.current?.focus();\n };\n const [context, setContext] = useState(readAiContext);\n const [pending, setPending] = useState<string[]>([]);\n const [error, setError] = useState(\"\");\n const [stopped, setStopped] = useState<string[]>([]);\n const activeRequests = useRef(new Map<string, string>());\n const [activity, setActivity] = useState<{\n key: string;\n reads: { method: AiReadActivity[\"method\"]; status: \"reading\" | \"ok\" | \"unavailable\" }[];\n }>({ key: \"\", reads: [] });\n const clusterReview = useRef<() => void>(() => {});\n const messagesElement = useRef<HTMLDivElement>(null);\n const [coveredByOverlay, setCoveredByOverlay] = useState(hasAiOverlay);\n useEffect(() => {\n let observedElements: Element[] = [];\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? undefined\n : new ResizeObserver(() => {\n setLauncherBottom(aiLauncherBottom());\n setLauncherLeft(aiLauncherLeft());\n });\n const updateDock = () => {\n setViewportWidth(window.innerWidth);\n setLauncherBottom(aiLauncherBottom());\n setLauncherLeft(aiLauncherLeft());\n const elements = [\n document.querySelector(\".Dock\"),\n document.querySelector('[data-testid=\"cluster-sidebar\"], .Sidebar'),\n ].filter((element): element is Element => !!element);\n if (\n elements.length !== observedElements.length ||\n elements.some((element, index) => element !== observedElements[index])\n ) {\n resizeObserver?.disconnect();\n observedElements = elements;\n for (const element of elements) resizeObserver?.observe(element);\n }\n };\n const update = () => {\n updateDock();\n setContext(readAiContext());\n setResourceDetailsOpen(hasAiResourceDetails());\n setCoveredByOverlay(hasAiOverlay());\n };\n const onActivity = (_event: unknown, value: unknown) => {\n if (!value || typeof value !== \"object\") return;\n const entry = value as { requestId?: string; method?: string; status?: string };\n const requestKey = activeRequests.current.get(entry.requestId ?? \"\");\n if (\n !requestKey ||\n requestKey !== readAiContext().clusterId ||\n ![\"pods\", \"nodes\", \"resources\", \"logs\"].includes(entry.method ?? \"\") ||\n ![\"reading\", \"ok\", \"unavailable\"].includes(entry.status ?? \"\")\n )\n return;\n const read = {\n method: entry.method as AiReadActivity[\"method\"],\n status: entry.status as \"reading\" | \"ok\" | \"unavailable\",\n };\n setActivity((previous) => ({\n key: requestKey,\n reads: [\n ...(previous.key === requestKey ? previous.reads.filter((item) => item.method !== read.method) : []),\n read,\n ],\n }));\n };\n ipcRenderer.on(AI_READ_ACTIVITY_CHANNEL, onActivity);\n window.addEventListener(\"resize\", updateDock);\n window.addEventListener(\"popstate\", update);\n update();\n const timer = window.setInterval(update, 500);\n const observer = new MutationObserver(update);\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"class\", \"style\", \"hidden\", \"open\"],\n });\n window.addEventListener(\"power-ai-open\", updateAndOpen);\n function updateAndOpen() {\n update();\n setOpen(true);\n clusterReview.current();\n }\n return () => {\n window.removeEventListener(\"resize\", updateDock);\n window.removeEventListener(\"popstate\", update);\n resizeObserver?.disconnect();\n ipcRenderer.removeListener(AI_READ_ACTIVITY_CHANNEL, onActivity);\n for (const requestId of activeRequests.current.keys()) {\n void ipcRenderer.invoke(AI_CANCEL_CHANNEL, requestId).catch(() => {});\n }\n activeRequests.current.clear();\n window.clearInterval(timer);\n observer.disconnect();\n window.removeEventListener(\"power-ai-open\", updateAndOpen);\n };\n }, []);\n useEffect(() => {\n setLauncherHidden(false);\n const onScroll = (event: Event) => {\n const target = event.target;\n if (!(target instanceof HTMLElement) || target.closest('.power-ai-panel, .Sidebar, [role=\"navigation\"], aside'))\n return;\n if (!target.closest('.ItemListLayout, .KubeObjectListLayout, main, [role=\"main\"]')) return;\n if (target.scrollHeight <= target.clientHeight || target.clientHeight <= 0) return;\n setLauncherHidden(target.scrollTop > 0 && target.scrollHeight - target.clientHeight - target.scrollTop <= 16);\n };\n document.addEventListener(\"scroll\", onScroll, true);\n return () => document.removeEventListener(\"scroll\", onScroll, true);\n }, [context.screen]);\n useEffect(() => {\n if (!open) return;\n const onEscape = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\" || hasAiOverlay()) return;\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n if (!dismissSuggestions.current()) setOpen(false);\n };\n window.addEventListener(\"keydown\", onEscape, true);\n return () => window.removeEventListener(\"keydown\", onEscape, true);\n }, [open]);\n useEffect(() => {\n if (!open || pinned) return;\n const onOutsideClick = (event: MouseEvent) => {\n const target = event.target;\n if (\n !(target instanceof Element) ||\n target.closest(\n \".power-ai-panel, .power-ai-launcher, .power-ai-overview-actions, [data-freelens-power-ai-overlay]\",\n )\n )\n return;\n setOpen(false);\n };\n document.addEventListener(\"click\", onOutsideClick, true);\n return () => document.removeEventListener(\"click\", onOutsideClick, true);\n }, [open, pinned]);\n useEffect(() => {\n const toggle = (event: KeyboardEvent) => {\n const mac = /Mac|iPhone|iPad/.test(navigator.platform);\n if (\n event.repeat ||\n event.isComposing ||\n event.keyCode === 229 ||\n event.altKey ||\n !event.shiftKey ||\n (mac ? !event.metaKey || event.ctrlKey : !event.ctrlKey || event.metaKey) ||\n event.code !== \"KeyY\" ||\n !preferences.enabled ||\n !isClusterDocument() ||\n hasAiOverlay()\n )\n return;\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n setContext(readAiContext());\n setOpen((value) => !value);\n };\n window.addEventListener(\"keydown\", toggle, true);\n return () => window.removeEventListener(\"keydown\", toggle, true);\n }, [preferences, isClusterDocument]);\n const availablePanelWidth = Math.max(1, viewportWidth - Math.max(0, launcherLeft - 16));\n const panelWidth = clampAiPanelWidth(preferences.chatPanelWidth ?? DEFAULT_AI_PANEL_WIDTH, availablePanelWidth);\n const shortcutLabel = /Mac|iPhone|iPad/.test(navigator.platform) ? \"⌘⇧Y\" : \"Ctrl+Shift+Y\";\n const key = context.clusterId ?? \"global\";\n const messages = preferences.conversations[key] ?? [];\n const busy = pending.includes(key);\n const readActivity = activity.key === key ? activity.reads : [];\n useEffect(() => {\n const element = messagesElement.current;\n if (element && following.current) element.scrollTop = element.scrollHeight;\n }, [messages.length, busy, open, key]);\n useEffect(() => {\n following.current = true;\n const element = messagesElement.current;\n if (element && open) element.scrollTop = element.scrollHeight;\n }, [open, key]);\n if (!preferences.enabled || !isClusterDocument() || coveredByOverlay) return null;\n const send = async (starter?: string) => {\n const question = expandAiShortcut(\n (starter ?? draft).trim(),\n AiShortcutsStore.getInstanceOrCreate<AiShortcutsStore>().shortcuts,\n );\n if (!question || busy) return;\n if (question.length > 20_000) {\n setError(\"Message is too long. Please keep it under 20,000 characters.\");\n return;\n }\n const requestContext = attachedAiContext(readAiContext());\n if ((requestContext.clusterId ?? \"global\") !== key) {\n setContext(requestContext);\n return;\n }\n following.current = true;\n const next: AiMessage[] = [...messages, { role: \"user\", text: question }];\n preferences.setMessages(key, next);\n setDraft(\"\");\n setError(\"\");\n setStopped((keys) => keys.filter((entry) => entry !== key));\n setActivity({ key, reads: [] });\n setPending((keys) => [...keys, key]);\n const provider = preferences.provider;\n const requestId = crypto.randomUUID();\n activeRequests.current.set(requestId, key);\n try {\n const response = await ipcRenderer.invoke(AI_CHAT_CHANNEL, {\n requestId,\n messages: next.slice(-80).reduceRight<AiMessage[]>((tail, message) => {\n if (tail.reduce((length, item) => length + item.text.length, 0) + message.text.length < 100_000)\n tail.unshift({ role: message.role, text: message.text });\n return tail;\n }, []),\n context: requestContext,\n systemPrompt: [preferences.systemPrompt, requestContext.clusterId ? preferences.clusterPrompt : \"\"]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n model: preferences.model,\n speed: preferences.speed,\n reasoningEffort: preferences.reasoningEffort,\n });\n if (activeRequests.current.get(requestId) !== key) return;\n if (!response || typeof response.text !== \"string\") throw new Error(\"Invalid response\");\n setActivity({\n key,\n reads: Array.isArray(response.reads)\n ? response.reads\n .filter(\n (read: AiReadActivity) =>\n [\"pods\", \"nodes\", \"resources\", \"logs\"].includes(read?.method) &&\n [\"ok\", \"unavailable\"].includes(read?.status),\n )\n .slice(0, 6)\n : [],\n });\n preferences.setMessages(key, [\n ...next,\n {\n role: \"assistant\",\n text: response.text,\n provider: response.provider === \"claude\" ? \"claude\" : provider,\n references: normalizeAiReferences(response.references),\n },\n ]);\n } catch (failure) {\n if (activeRequests.current.get(requestId) !== key) return;\n const code = String(failure).match(/FREELENS_AI_([A-Z_]+)/)?.[1];\n const messages: Record<string, string> = {\n READ_LIMIT: \"The assistant reached the read limit. Try a more specific question.\",\n TIMEOUT: \"The request timed out. Please try again.\",\n INVALID_REPLY: \"The assistant returned an incomplete reply. Please try again.\",\n CLI_FAILURE: \"The selected CLI request failed. Check your model access or try again.\",\n CANCELLED: \"The request was canceled.\",\n UNSAFE_POLICY:\n \"Claude managed policy cannot be safely isolated. Use Codex or ask your administrator to disable managed hooks and command helpers.\",\n INPUT_LIMIT: \"The request is too large. Start a new chat or shorten the message.\",\n };\n setError(\n (code && messages[code]) ||\n \"Unable to complete the request. Check that the selected CLI is installed and signed in, then try again.\",\n );\n } finally {\n activeRequests.current.delete(requestId);\n setPending((keys) => keys.filter((entry) => entry !== key));\n }\n };\n const stopResponse = () => {\n const requestId = [...activeRequests.current].find(([, requestKey]) => requestKey === key)?.[0];\n if (!requestId) return;\n activeRequests.current.delete(requestId);\n setStopped((keys) => [...keys.filter((entry) => entry !== key), key]);\n setActivity({ key, reads: [] });\n setError(\"\");\n void ipcRenderer.invoke(AI_CANCEL_CHANNEL, requestId).catch(() => {});\n };\n clusterReview.current = () => {\n const currentKey = readAiContext().clusterId;\n if (!currentKey || currentKey !== key || preferences.conversations[currentKey]?.length) return;\n void send(\n preferences.clusterPrompt.trim() ||\n \"Review this cluster using read-only queries and summarize its health and useful next steps.\",\n );\n };\n return (\n <>\n <style>{styles}</style>\n {!open && (\n <button\n type=\"button\"\n className={`power-ai-launcher${launcherHidden ? \" power-ai-launcher-hidden\" : \"\"}`}\n aria-hidden={launcherHidden || undefined}\n tabIndex={launcherHidden ? -1 : 0}\n style={{\n bottom: launcherBottom,\n left: resourceDetailsOpen ? launcherLeft : \"auto\",\n right: resourceDetailsOpen ? \"auto\" : 16,\n }}\n onClick={() => setOpen(true)}\n aria-label=\"Open AI assistant\"\n title={`Open AI assistant (${shortcutLabel})`}\n >\n <span aria-hidden=\"true\">\n <AiIcon material=\"chat_bubble_outline\" size={16} />\n </span>{\" \"}\n AI\n </button>\n )}\n {open && (\n <aside\n className=\"power-ai-panel\"\n aria-label=\"AI assistant\"\n style={{ \"--power-ai-font-size\": `${preferences.chatFontSize ?? 14}px`, width: panelWidth } as CSSProperties}\n >\n <AiResizeHandle\n width={panelWidth}\n available={availablePanelWidth}\n onChange={(width) => preferences.setChatPanelWidth(width)}\n />\n <header>\n <strong className=\"power-ai-title\">\n <span className=\"power-ai-brand\" title=\"AI assistant\">\n <AiIcon material=\"auto_awesome\" size={18} /> AI\n </span>{\" \"}\n Assistant\n </strong>\n <button\n type=\"button\"\n disabled={busy}\n aria-label=\"New chat\"\n title=\"Clear this conversation and start a new chat\"\n onClick={() => {\n preferences.setMessages(key, []);\n setStopped((keys) => keys.filter((entry) => entry !== key));\n setActivity({ key, reads: [] });\n setError(\"\");\n }}\n >\n <AiIcon material=\"add_comment\" size={16} /> New chat\n </button>\n <button\n type=\"button\"\n className=\"power-ai-pin\"\n aria-label=\"Pin AI assistant\"\n aria-pressed={pinned}\n title={pinned ? \"Unpin to close when clicking outside\" : \"Pin to keep the assistant open\"}\n onClick={() => setPinned((value) => !value)}\n >\n <AiIcon material=\"push_pin\" size={18} />\n </button>\n <button\n type=\"button\"\n onPointerDown={(event) => event.stopPropagation()}\n onMouseDown={(event) => event.stopPropagation()}\n onClick={(event) => {\n event.stopPropagation();\n setOpen(false);\n }}\n className=\"power-ai-close\"\n aria-label=\"Close AI assistant\"\n title=\"Close AI assistant\"\n >\n <span aria-hidden=\"true\">\n <AiIcon material=\"close\" size={18} />\n </span>\n </button>\n </header>\n <div className=\"power-ai-context\">\n {context.clusterId ? \"Cluster conversation\" : \"General conversation\"} · {context.screen}\n {context.resource && ` · ${context.resource.kind}/${context.resource.name}`}\n <br />\n Only screen and resource metadata are attached automatically.\n </div>\n <div\n className=\"power-ai-messages\"\n onScroll={(event) => {\n const element = event.currentTarget;\n following.current = element.scrollHeight - element.scrollTop - element.clientHeight < 48;\n }}\n aria-live=\"polite\"\n ref={messagesElement}\n >\n {messages.length === 0 && (\n <div className=\"power-ai-starters\">\n <p style={{ marginBottom: 12 }}>Ask about this screen or your cluster:</p>\n <AiStarterPrompts\n disabled={busy}\n onSelect={(prompt) => {\n void send(prompt);\n }}\n />\n </div>\n )}\n {messages.map((message, index) => (\n <div className={`power-ai-message power-ai-message-${message.role}`} key={index}>\n <strong>\n {message.role === \"user\" ? (\n <span title=\"You\">\n <AiIcon material=\"person_outline\" size={16} />\n </span>\n ) : (\n <AiProviderIcon provider={message.provider === \"claude\" ? \"claude\" : \"codex\"} />\n )}\n {message.role === \"user\" ? \"You\" : message.provider === \"claude\" ? \"Claude\" : \"Codex\"}\n {message.role === \"assistant\" && <AiCopyAnswer text={message.text} />}\n </strong>\n <AiMessageContent text={message.text} />\n {message.role === \"assistant\" && context.clusterId && (\n <AiResourceReferences\n clusterId={context.clusterId}\n references={message.references}\n text={message.text}\n onOpened={() => setOpen(false)}\n />\n )}\n </div>\n ))}\n {readActivity.length > 0 && (\n <div\n className=\"power-ai-read-activity\"\n style={{ fontSize: 11, color: \"var(--textColorSecondary)\", margin: \"8px 16px\" }}\n >\n {readActivity.map((read, index) => (\n <span\n key={index}\n title={`${read.method} · ${read.status === \"reading\" ? \"reading\" : read.status === \"ok\" ? \"read\" : \"unavailable\"}`}\n data-method={read.method}\n data-status={read.status}\n style={{ marginRight: 10 }}\n >\n <AiIcon\n material={\n read.status === \"reading\"\n ? \"sync\"\n : read.status === \"ok\"\n ? \"check_circle_outline\"\n : \"info_outline\"\n }\n size={13}\n />{\" \"}\n {read.method} ·{\" \"}\n {read.status === \"reading\" ? \"reading\" : read.status === \"ok\" ? \"read\" : \"unavailable\"}\n </span>\n ))}\n </div>\n )}\n {busy && (\n <p className=\"power-ai-thinking\" role=\"status\">\n {stopped.includes(key) ? \"Stopping response\" : \"Thinking\"}\n <span className=\"power-ai-dots\" aria-hidden=\"true\">\n <span>.</span>\n <span>.</span>\n <span>.</span>\n </span>\n </p>\n )}\n {!busy && stopped.includes(key) && (\n <p className=\"power-ai-cancellation\" role=\"status\">\n Response stopped{\" \"}\n <button\n type=\"button\"\n aria-label=\"Dismiss cancellation\"\n className=\"power-ai-dismiss\"\n title=\"Dismiss\"\n onClick={() => setStopped((keys) => keys.filter((entry) => entry !== key))}\n >\n <AiIcon material=\"close\" size={14} />\n </button>\n </p>\n )}\n {error && <p role=\"alert\">{error}</p>}\n </div>\n <form\n onSubmit={(event) => {\n event.preventDefault();\n void send();\n }}\n >\n {suggestions.length > 0 && (\n <div\n className=\"power-ai-autocomplete\"\n role=\"listbox\"\n id=\"power-ai-commands\"\n aria-label=\"Prompt shortcuts\"\n >\n {suggestions.map((shortcut, index) => (\n <button\n type=\"button\"\n role=\"option\"\n id={`power-ai-command-${index}`}\n aria-selected={index === suggestionIndex % suggestions.length}\n key={shortcut.id}\n title={`Insert /${shortcut.command}: ${shortcut.label}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => selectSuggestion(index)}\n >\n <span>/{shortcut.command}</span>\n <span>{shortcut.label}</span>\n </button>\n ))}\n </div>\n )}\n <AiContextPreview context={attachedAiContext(context)} />\n <textarea\n ref={composer}\n aria-controls={suggestions.length ? \"power-ai-commands\" : undefined}\n aria-expanded={suggestions.length > 0}\n aria-activedescendant={\n suggestions.length ? `power-ai-command-${suggestionIndex % suggestions.length}` : undefined\n }\n autoFocus\n aria-label=\"Message\"\n placeholder=\"Ask about this cluster…\"\n onKeyDown={(event) => {\n if (event.nativeEvent.isComposing || event.keyCode === 229) return;\n if (suggestions.length && !event.shiftKey) {\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n setSuggestionIndex(\n (index) =>\n (index + (event.key === \"ArrowDown\" ? 1 : suggestions.length - 1)) % suggestions.length,\n );\n return;\n }\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n event.preventDefault();\n selectSuggestion(suggestionIndex % suggestions.length);\n return;\n }\n }\n if (\n event.key === \"Enter\" &&\n !event.shiftKey &&\n !event.nativeEvent.isComposing &&\n event.keyCode !== 229\n ) {\n event.preventDefault();\n if (!busy) void send();\n }\n }}\n value={draft}\n onChange={(event) => {\n setDraft(event.target.value);\n setSuggestionIndex(0);\n setDismissedDraft(undefined);\n }}\n disabled={busy}\n />\n <div className=\"power-ai-composer-footer\">\n <span>Enter to send · Shift+Enter for newline</span>\n {busy ? (\n <button\n type=\"button\"\n aria-label=\"Stop response\"\n disabled={stopped.includes(key)}\n onClick={stopResponse}\n >\n <AiIcon material=\"stop\" size={16} /> Stop\n </button>\n ) : (\n <button type=\"submit\" disabled={!draft.trim()} aria-label=\"Send\">\n <AiIcon material=\"send\" size={16} />\n </button>\n )}\n </div>\n </form>\n </aside>\n )}\n </>\n );\n});\n\nexport function startAiChat(isClusterDocument: () => boolean = isAiClusterDocument): () => void {\n const container = document.createElement(\"div\");\n container.dataset.freelensPowerAi = \"\";\n document.body.append(container);\n let mounted = false;\n let overviewActions: HTMLDivElement | undefined;\n let overviewIcon: HTMLSpanElement | undefined;\n let overviewLabel: HTMLSpanElement | undefined;\n let overviewResize: ResizeObserver | undefined;\n const updateOverviewLabel = () => {\n const overview = overviewActions?.nextElementSibling;\n const compact = Boolean(overview?.querySelector(\"[data-freelens-power-monitoring]\") && overview.clientWidth > 960);\n const label = compact ? \"Ask AI\" : \"Ask about cluster\";\n if (overviewLabel && overviewLabel.textContent !== label) overviewLabel.textContent = label;\n overviewActions?.querySelector(\"button\")?.setAttribute(\"aria-label\", compact ? \"Ask AI about cluster\" : label);\n };\n const removeOverview = () => {\n overviewResize?.disconnect();\n overviewResize = undefined;\n if (overviewIcon) ReactDOM.unmountComponentAtNode(overviewIcon);\n overviewIcon = undefined;\n overviewLabel = undefined;\n overviewActions?.remove();\n overviewActions = undefined;\n };\n const preferences = AiPreferencesStore.getInstanceOrCreate<AiPreferencesStore>();\n const reconcile = () => {\n const overview =\n preferences.enabled &&\n isClusterDocument() &&\n Renderer.Catalog.activeCluster.get() &&\n document.querySelector('[data-testid=\"cluster-overview-page\"]');\n if (!overview) {\n removeOverview();\n return;\n }\n if (overviewActions?.isConnected && overviewActions.nextElementSibling === overview) {\n updateOverviewLabel();\n return;\n }\n removeOverview();\n overviewActions = document.createElement(\"div\");\n overviewActions.className = \"power-ai-overview-actions\";\n const overviewButton = document.createElement(\"button\");\n overviewButton.type = \"button\";\n overviewButton.setAttribute(\"aria-label\", \"Ask about cluster\");\n overviewButton.title = \"Open the AI assistant to ask about this cluster\";\n overviewIcon = document.createElement(\"span\");\n overviewIcon.setAttribute(\"aria-hidden\", \"true\");\n overviewLabel = document.createElement(\"span\");\n overviewButton.append(overviewIcon, overviewLabel);\n overviewButton.onclick = () => window.dispatchEvent(new Event(\"power-ai-open\"));\n overviewActions.append(overviewButton);\n overview.before(overviewActions);\n updateOverviewLabel();\n if (typeof ResizeObserver !== \"undefined\") {\n overviewResize = new ResizeObserver(updateOverviewLabel);\n overviewResize.observe(overview);\n }\n ReactDOM.render(<AiIcon material=\"auto_awesome\" size={16} />, overviewIcon);\n };\n const observer = new MutationObserver(reconcile);\n const stop = autorun(() => {\n if (preferences.enabled && !mounted) {\n observer.observe(document.body, { childList: true, subtree: true });\n mounted = true;\n ReactDOM.render(<AiChat isClusterDocument={isClusterDocument} />, container);\n } else if (!preferences.enabled && mounted) {\n observer.disconnect();\n ReactDOM.unmountComponentAtNode(container);\n mounted = false;\n }\n reconcile();\n });\n return () => {\n stop();\n observer.disconnect();\n removeOverview();\n ReactDOM.unmountComponentAtNode(container);\n container.remove();\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai.js","names":[],"sources":["../../src/renderer/ai.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { ipcRenderer } from \"electron\";\nimport { autorun } from \"mobx\";\nimport { observer } from \"mobx-react\";\nimport { type CSSProperties, useEffect, useRef, useState } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { AI_CHAT_CHANNEL, AI_READ_ACTIVITY_CHANNEL, type AiReadActivity } from \"../common/ai\";\nimport { AI_CANCEL_CHANNEL, attachedAiContext, normalizeAiReferences } from \"../common/ai-extras\";\nimport { expandAiShortcut } from \"../common/ai-shortcuts\";\nimport { type AiMessage, AiPreferencesStore } from \"../common/store/ai-preferences-store\";\nimport { AiShortcutsStore } from \"../common/store/ai-shortcuts-store\";\nimport { AiCopyAnswer } from \"./ai-copy-answer\";\nimport { AiContextPreview, AiResourceReferences } from \"./ai-extras\";\nimport { AiIcon } from \"./ai-icon\";\nimport { AiMessageContent } from \"./ai-message\";\nimport { AiProviderIcon } from \"./ai-provider-icon\";\nimport { AiResizeHandle, clampAiPanelWidth, DEFAULT_AI_PANEL_WIDTH } from \"./ai-resize\";\nimport { AiStarterPrompts } from \"./ai-shortcuts\";\nimport {\n type AiTerminalAttachment,\n AiTerminalContext,\n activeAiTerminal,\n captureAiTerminal,\n} from \"./ai-terminal-context\";\n\nexport interface AiScreenContext {\n clusterId?: string;\n screen?: string;\n resource?: { kind?: string; namespace?: string; name?: string };\n}\n\nexport function readAiContext(): AiScreenContext {\n const clusterId = Renderer.Catalog.activeCluster.get()?.metadata.uid;\n const screen = window.location.pathname;\n const details = new URLSearchParams(window.location.search).get(\"kube-details\");\n const match =\n details?.match(/^\\/api(?:\\/v\\d+)?\\/namespaces\\/([^/]+)\\/([^/]+)\\/([^/]+)$/) ??\n details?.match(/^\\/apis\\/[^/]+\\/[^/]+\\/namespaces\\/([^/]+)\\/([^/]+)\\/([^/]+)$/);\n const clusterResource =\n details?.match(/^\\/api\\/[^/]+\\/([^/]+)\\/([^/]+)$/) ?? details?.match(/^\\/apis\\/[^/]+\\/[^/]+\\/([^/]+)\\/([^/]+)$/);\n const resource = match\n ? { namespace: match[1], kind: match[2], name: match[3] }\n : clusterResource\n ? { kind: clusterResource[1], name: clusterResource[2] }\n : undefined;\n return { clusterId, screen, ...(resource ? { resource } : {}) };\n}\n\nexport function isAiClusterDocument(): boolean {\n return window.top !== window && Boolean(Renderer.Catalog.activeCluster.get());\n}\n\nexport function aiLauncherBottom(): number {\n const dock = document.querySelector<HTMLElement>(\".Dock\");\n if (!dock) return 16;\n const rect = dock.getBoundingClientRect();\n const style = window.getComputedStyle(dock);\n if (\n dock.hidden ||\n style.display === \"none\" ||\n style.visibility === \"hidden\" ||\n rect.width <= 0 ||\n rect.height <= 0 ||\n rect.top <= 0 ||\n rect.top >= window.innerHeight\n )\n return 16;\n return Math.max(16, window.innerHeight - rect.top + 16);\n}\n\nexport function aiLauncherLeft(): number {\n const sidebar = document.querySelector<HTMLElement>('[data-testid=\"cluster-sidebar\"], .Sidebar');\n const dock = document.querySelector<HTMLElement>(\".Dock\");\n let contentLeft = 0;\n for (const [element, edge] of [\n [sidebar, \"right\"],\n [dock, \"left\"],\n ] as const) {\n if (!element || element.hidden) continue;\n const style = window.getComputedStyle(element);\n const rect = element.getBoundingClientRect();\n if (style.display === \"none\" || style.visibility === \"hidden\" || rect.width <= 0) continue;\n const value = rect[edge];\n if (Number.isFinite(value) && value >= 0 && value < window.innerWidth - 80)\n contentLeft = Math.max(contentLeft, value);\n }\n return contentLeft + 16;\n}\n\nexport function hasAiResourceDetails(): boolean {\n if (new URLSearchParams(window.location.search).get(\"kube-details\")) return true;\n return Array.from(\n document.querySelectorAll<HTMLElement>(\".Drawer.KubeObjectDetails, .Drawer.ReleaseDetails, .DetailsDrawer\"),\n ).some((element) => {\n const style = window.getComputedStyle(element);\n const rect = element.getBoundingClientRect();\n return (\n !element.hidden && style.display !== \"none\" && style.visibility !== \"hidden\" && rect.width > 0 && rect.height > 0\n );\n });\n}\n\nexport function hasAiOverlay(): boolean {\n return Array.from(document.querySelectorAll<HTMLElement>('[role=\"dialog\"], dialog[open], .Dialog')).some(\n (element) => {\n const style = window.getComputedStyle(element);\n return !element.hidden && style.display !== \"none\" && style.visibility !== \"hidden\";\n },\n );\n}\n\nconst styles = `\n@keyframes power-ai-spin { to { transform: rotate(360deg); } }\n@keyframes power-ai-dot { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }\nbody:has(.AddRemoveButtons .remove-button:not([data-freelens-power-read-only])) .power-ai-launcher { display: none; }\n.power-ai-read-activity > span { display: inline-flex; align-items: center; gap: 4px; }\n.power-ai-read-activity [data-status=\"reading\"] .Icon { animation: power-ai-spin 1.2s linear infinite; }\n.power-ai-thinking { margin: 12px 16px 18px; line-height: 1.5; color: var(--textColorSecondary); }\n.power-ai-dots > span { animation: power-ai-dot 1.3s ease-in-out infinite; }\n.power-ai-dots > span:nth-child(2) { animation-delay: .15s; }\n.power-ai-dots > span:nth-child(3) { animation-delay: .3s; }\n@media (prefers-reduced-motion: reduce) { .power-ai-read-activity [data-status=\"reading\"] .Icon, .power-ai-dots > span { animation: none; } }\n@keyframes power-ai-enter { from { transform: translateX(100%); } to { transform: translateX(0); } }\n:root .power-ai-launcher { position: fixed; bottom: 16px; left: auto; right: 16px; z-index: 100; display: inline-flex; align-items: center; gap: 6px; min-width: 0; min-height: 0; height: 34px; border: 1px solid var(--primary, #5896ff); border-radius: 24px; padding: 0 13px; background: var(--contentColor, #242424); color: var(--textColorAccent); box-shadow: 0 3px 12px #0003; font: inherit; font-size: 12px; font-weight: 500; line-height: 1; cursor: pointer; transition: opacity 180ms ease, background-color 140ms ease, box-shadow 140ms ease, transform 180ms ease; }\n.power-ai-overview-actions { position: relative; z-index: 5; height: 0; min-height: 0; flex: 0 0 0; pointer-events: none; }\n.power-ai-overview-actions + [data-testid=\"cluster-overview-page\"] [data-monitoring-summaries] { --power-monitoring-summary-top: 56px; }\n.power-ai-overview-actions button { transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease, box-shadow 160ms ease; position: absolute; top: 12px; right: 12px; pointer-events: auto; box-shadow: 0 2px 8px #0002; display: inline-flex; flex: 0 0 auto; width: auto; align-items: center; gap: 6px; min-height: 32px; padding: 6px 12px; font: inherit; font-size: 12px; border: 1px solid var(--borderFaintColor); border-radius: 10px; color: var(--textColorPrimary); background: var(--contentColor); cursor: pointer; }\n.power-ai-overview-actions button:hover { border-color: var(--primary); color: var(--textColorAccent); background: var(--contentColor); }\n.power-ai-overview-actions button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n.power-ai-launcher.power-ai-launcher-hidden { opacity: 0; transform: translateY(8px); pointer-events: none; }\n.power-ai-launcher .Icon { color: inherit; }\n.power-ai-launcher:hover { background: color-mix(in srgb, var(--primary, #5896ff) 12%, var(--contentColor, #242424)); box-shadow: 0 4px 12px #0003; transform: translateY(-1px); }\n.power-ai-launcher:active { transform: translateY(0); box-shadow: 0 2px 6px #0002; }\n@media (prefers-reduced-motion: reduce) { :root .power-ai-launcher { transition: none; } .power-ai-launcher:hover, .power-ai-launcher:active { transform: none; } }\n.power-ai-launcher:focus-visible { outline: 2px solid var(--primary, #5896ff); outline-offset: 3px; }\n.power-ai-panel { position: fixed; right: 0; top: 0; bottom: 0; width: min(560px, 100vw); z-index: 10001; display: flex; flex-direction: column; background: var(--contentColor, #242424); color: var(--textColorAccent, white); animation: power-ai-enter 160ms ease-out; border-left: 1px solid var(--borderFaintColor); box-shadow: -4px 0 24px #0004; }\n.power-ai-resize-handle { position: absolute; left: -4px; top: 0; bottom: 0; width: 8px; z-index: 2; cursor: col-resize; touch-action: none; }\n.power-ai-resize-handle:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }\n.power-ai-panel header { padding: 16px; display: flex; gap: 10px; flex-shrink: 0; }\n.power-ai-panel header { border-bottom: 1px solid var(--borderFaintColor); justify-content: space-between; align-items: center; }\n.power-ai-messages { overflow: auto; flex: 1; min-height: 0; padding: 24px 16px; font-size: var(--power-ai-font-size, 14px); line-height: 1.65; overscroll-behavior: contain; }\n.power-ai-message { overflow-wrap: anywhere; padding: 14px 16px; margin-bottom: 20px; color: var(--textColorAccent); border: 1px solid var(--borderFaintColor); border-radius: 8px; }\n.power-ai-panel button { padding: 7px 10px; border: 1px solid var(--borderFaintColor); border-radius: 8px; background: var(--contentColor); color: var(--textColorPrimary); cursor: pointer; }\n:root .power-ai-panel header button:is(.power-ai-close, .power-ai-pin) { width: 30px; height: 30px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); }\n:root .power-ai-panel header button:is(.power-ai-close, .power-ai-pin):not(:disabled):not(.disabled):hover { color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }\n:root .power-ai-panel header button:is(.power-ai-close, .power-ai-pin):focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n:root .power-ai-panel button.power-ai-copy-answer { width: 24px; height: 24px; padding: 0; margin-left: auto; flex-shrink: 0; justify-content: center; border: 0; background: transparent; color: var(--textColorSecondary); }\n:root .power-ai-panel button.power-ai-copy-answer:not(:disabled):not(.disabled):hover { color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }\n:root .power-ai-panel button.power-ai-copy-answer:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n.power-ai-cancellation { display: flex; align-items: center; gap: 6px; }\n:root .power-ai-panel button.power-ai-dismiss { width: 24px; height: 24px; padding: 0; justify-content: center; border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); }\n:root .power-ai-panel button.power-ai-dismiss:hover { color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }\n:root .power-ai-panel button.power-ai-dismiss:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n.power-ai-panel button:disabled { opacity: 0.5; cursor: default; }\n .power-ai-panel textarea { display: block; width: 100%; box-sizing: border-box; min-width: 0; min-height: 64px; max-height: 180px; field-sizing: content; padding: 12px 16px 6px; border: 0; border-radius: 12px; background: transparent; color: var(--textColorAccent); font: inherit; font-size: var(--power-ai-font-size, 14px); line-height: 1.5; resize: none; }\n.power-ai-panel textarea::placeholder { color: var(--textColorSecondary); opacity: 1; }\n.power-ai-panel textarea:focus { outline: none; }\n.power-ai-composer-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 10px 10px 16px; }\n.power-ai-composer-footer > span { color: var(--textColorSecondary); font-size: 11px; line-height: 1.5; }\n:root .power-ai-panel form button[type=\"submit\"] { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 34px; width: 34px; height: 34px; padding: 0; border-radius: 10px; }\n:root .power-ai-panel form button[type=\"submit\"]:not(:disabled):not(.disabled) { background-color: var(--primary); border-color: var(--primary); color: white; }\n:root .power-ai-panel form button[type=\"submit\"]:not(:disabled):not(.disabled):hover { background-color: color-mix(in srgb, var(--primary) 88%, white 12%); border-color: color-mix(in srgb, var(--primary) 88%, white 12%); color: white; }\n:root .power-ai-panel form button[type=\"submit\"]:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }\n:root .power-ai-panel form button[type=\"submit\"]:disabled { background-color: var(--contentColor); border-color: var(--borderFaintColor); color: var(--textColorSecondary); }\n.power-ai-message-user { border-color: color-mix(in srgb, var(--primary) 28%, var(--borderFaintColor)); background: color-mix(in srgb, var(--primary) 7%, var(--mainBackground)); }\n.power-ai-context { padding: 10px 20px; line-height: 1.5; border-bottom: 1px solid var(--borderFaintColor); font-size: 12px; color: var(--textColorSecondary); overflow-wrap: anywhere; }\n.power-ai-title, .power-ai-panel button { display: inline-flex; align-items: center; gap: 6px; }\n.power-ai-title { margin-right: auto; white-space: nowrap; color: var(--textColorAccent); }\n.power-ai-brand { display: inline-flex; align-items: center; gap: 6px; color: var(--primary); }\n.power-ai-brand .Icon { color: inherit; }\n:root .power-ai-panel header button.power-ai-pin[aria-pressed=\"true\"] { color: var(--primary); }\n.power-ai-panel header > button { flex-shrink: 0; }\n.power-ai-panel form { position: relative; flex-shrink: 0; margin: 0 16px 16px; border: 1px solid var(--borderFaintColor); border-radius: 12px; background: var(--mainBackground); transition: border-color 160ms ease; }\n.power-ai-panel form > .power-ai-context-preview { padding: 8px 48px 4px 16px !important; min-height: 34px; margin: 0; box-sizing: border-box; }\n.power-ai-panel form:focus-within { border-color: var(--primary); }\n.power-ai-message > strong { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 500; color: var(--textColorSecondary); margin-bottom: 10px; }\n.power-ai-message-assistant { border-color: transparent; background: transparent; }\n.power-ai-markdown { line-height: 1.65; font-size: var(--power-ai-font-size, 14px); color: var(--textColorAccent); }\n.power-ai-markdown p { margin: 0 0 14px; white-space: pre-wrap; }\n.power-ai-markdown p:last-child { margin-bottom: 0; }\n.power-ai-markdown ul, .power-ai-markdown ol { padding-left: 24px; margin: 10px 0 16px; }\n.power-ai-markdown ul { list-style: disc; }\n.power-ai-markdown ol { list-style: decimal; }\n.power-ai-markdown li { margin: 5px 0; }\n.power-ai-markdown li > ul, .power-ai-markdown li > ol { margin: 6px 0; }\n.power-ai-markdown li > p { margin-bottom: 6px; }\n.power-ai-markdown :is(h1, h2, h3, h4, h5, h6) { color: var(--textColorAccent); font-weight: 600; line-height: 1.4; margin: 24px 0 12px; }\n.power-ai-markdown :is(h1, h2, h3, h4, h5, h6):first-child { margin-top: 0; }\n.power-ai-markdown h1 { font-size: 1.43em; }\n.power-ai-markdown h2 { font-size: 1.29em; }\n.power-ai-markdown h3 { font-size: 1.14em; }\n.power-ai-markdown :is(h4, h5, h6) { font-size: 1em; }\n.power-ai-markdown blockquote { margin: 16px 0; padding: 4px 14px; border-left: 3px solid var(--borderColor); color: var(--textColorSecondary); }\n.power-ai-markdown blockquote > p:last-child { margin-bottom: 0; }\n.power-ai-markdown table { display: block; max-width: 100%; overflow-x: auto; margin: 16px 0; border-collapse: collapse; font-size: max(10px, calc(var(--power-ai-font-size, 14px) - 1px)); }\n.power-ai-markdown th, .power-ai-markdown td { padding: 9px 12px; border: 1px solid var(--borderFaintColor); text-align: left; }\n.power-ai-markdown th { font-weight: 600; background: color-mix(in srgb, var(--textColorAccent) 5%, transparent); }\n.power-ai-markdown a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }\n.power-ai-markdown hr { margin: 20px 0; border: 0; border-top: 1px solid var(--borderFaintColor); }\n.power-ai-markdown code { font-family: var(--font-monospace, monospace); font-size: max(10px, calc(var(--power-ai-font-size, 14px) - 1px)); background: color-mix(in srgb, var(--textColorAccent) 8%, transparent); padding: 1px 4px; border-radius: 4px; }\n.power-ai-code { margin: 12px 0; border: 1px solid var(--borderFaintColor); border-radius: 8px; overflow: hidden; background: var(--mainBackground); }\n.power-ai-code-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 8px; border-bottom: 1px solid var(--borderFaintColor); color: var(--textColorSecondary); font-size: 11px; }\n.power-ai-code-toolbar > div { display: flex; gap: 4px; }\n.power-ai-code-toolbar button { padding: 4px 6px; font-size: 11px; }\n.power-ai-code pre { margin: 0; padding: 12px; overflow-x: auto; white-space: pre; }\n.power-ai-code pre code { padding: 0; background: transparent; }\n.power-ai-code-hint, .power-ai-code-feedback:not(:empty) { padding: 0 12px 10px; color: var(--textColorSecondary); font-size: 11px; }\n.power-ai-autocomplete { position: absolute; bottom: calc(100% + 8px); left: 0; right: 0; max-height: 240px; overflow-y: auto; padding: 6px; border: 1px solid var(--borderColor); border-radius: 10px; background: var(--contentColor); box-shadow: 0 4px 16px #0003; }\n.power-ai-autocomplete button { display: flex; width: 100%; justify-content: space-between; gap: 12px; border: 0; text-align: left; }\n.power-ai-autocomplete button[aria-selected=\"true\"] { background: color-mix(in srgb, var(--primary) 14%, var(--contentColor)); color: var(--textColorAccent); }\n.power-ai-autocomplete button > span:last-child { color: var(--textColorSecondary); font-size: 12px; }\n@media (prefers-reduced-motion: reduce) { .power-ai-panel { animation: none; } }\n`;\n\nconst AiChat = observer(({ isClusterDocument }: { isClusterDocument: () => boolean }) => {\n const preferences = AiPreferencesStore.getInstanceOrCreate<AiPreferencesStore>();\n const [open, setOpen] = useState(false);\n const [pinned, setPinned] = useState(false);\n const [launcherBottom, setLauncherBottom] = useState(aiLauncherBottom);\n const [launcherLeft, setLauncherLeft] = useState(aiLauncherLeft);\n const [resourceDetailsOpen, setResourceDetailsOpen] = useState(hasAiResourceDetails);\n const [viewportWidth, setViewportWidth] = useState(window.innerWidth);\n const [launcherHidden, setLauncherHidden] = useState(false);\n const [draft, setDraft] = useState(\"\");\n const [terminalAttachment, setTerminalAttachment] = useState<AiTerminalAttachment>();\n const [suggestionIndex, setSuggestionIndex] = useState(0);\n const [dismissedDraft, setDismissedDraft] = useState<string>();\n const suggestions =\n /^\\/[^\\s]*$/.test(draft) && dismissedDraft !== draft\n ? AiShortcutsStore.getInstanceOrCreate<AiShortcutsStore>().shortcuts.filter((shortcut) =>\n `${shortcut.command} ${shortcut.label}`.toLowerCase().includes(draft.slice(1).toLowerCase()),\n )\n : [];\n const dismissSuggestions = useRef<() => boolean>(() => false);\n dismissSuggestions.current = () => {\n if (!suggestions.length) return false;\n setDismissedDraft(draft);\n return true;\n };\n const following = useRef(true);\n const composer = useRef<HTMLTextAreaElement>(null);\n const selectSuggestion = (index: number) => {\n const shortcut = suggestions[index];\n if (!shortcut) return;\n setDraft(`/${shortcut.command} `);\n setSuggestionIndex(0);\n composer.current?.focus();\n };\n const [context, setContext] = useState(readAiContext);\n const [pending, setPending] = useState<string[]>([]);\n const [error, setError] = useState(\"\");\n const [stopped, setStopped] = useState<string[]>([]);\n const activeRequests = useRef(new Map<string, string>());\n const [activity, setActivity] = useState<{\n key: string;\n reads: { method: AiReadActivity[\"method\"]; status: \"reading\" | \"ok\" | \"unavailable\" }[];\n }>({ key: \"\", reads: [] });\n const clusterReview = useRef<() => void>(() => {});\n const messagesElement = useRef<HTMLDivElement>(null);\n const [coveredByOverlay, setCoveredByOverlay] = useState(hasAiOverlay);\n useEffect(() => {\n let observedElements: Element[] = [];\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? undefined\n : new ResizeObserver(() => {\n setLauncherBottom(aiLauncherBottom());\n setLauncherLeft(aiLauncherLeft());\n });\n const updateDock = () => {\n setViewportWidth(window.innerWidth);\n setLauncherBottom(aiLauncherBottom());\n setLauncherLeft(aiLauncherLeft());\n const elements = [\n document.querySelector(\".Dock\"),\n document.querySelector('[data-testid=\"cluster-sidebar\"], .Sidebar'),\n ].filter((element): element is Element => !!element);\n if (\n elements.length !== observedElements.length ||\n elements.some((element, index) => element !== observedElements[index])\n ) {\n resizeObserver?.disconnect();\n observedElements = elements;\n for (const element of elements) resizeObserver?.observe(element);\n }\n };\n const update = () => {\n updateDock();\n setContext(readAiContext());\n setResourceDetailsOpen(hasAiResourceDetails());\n setCoveredByOverlay(hasAiOverlay());\n };\n const onActivity = (_event: unknown, value: unknown) => {\n if (!value || typeof value !== \"object\") return;\n const entry = value as { requestId?: string; method?: string; status?: string };\n const requestKey = activeRequests.current.get(entry.requestId ?? \"\");\n if (\n !requestKey ||\n requestKey !== readAiContext().clusterId ||\n ![\"pods\", \"nodes\", \"resources\", \"logs\"].includes(entry.method ?? \"\") ||\n ![\"reading\", \"ok\", \"unavailable\"].includes(entry.status ?? \"\")\n )\n return;\n const read = {\n method: entry.method as AiReadActivity[\"method\"],\n status: entry.status as \"reading\" | \"ok\" | \"unavailable\",\n };\n setActivity((previous) => ({\n key: requestKey,\n reads: [\n ...(previous.key === requestKey ? previous.reads.filter((item) => item.method !== read.method) : []),\n read,\n ],\n }));\n };\n ipcRenderer.on(AI_READ_ACTIVITY_CHANNEL, onActivity);\n window.addEventListener(\"resize\", updateDock);\n window.addEventListener(\"popstate\", update);\n update();\n const timer = window.setInterval(update, 500);\n const observer = new MutationObserver(update);\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"class\", \"style\", \"hidden\", \"open\"],\n });\n window.addEventListener(\"power-ai-open\", updateAndOpen);\n function updateAndOpen() {\n update();\n setOpen(true);\n clusterReview.current();\n }\n return () => {\n window.removeEventListener(\"resize\", updateDock);\n window.removeEventListener(\"popstate\", update);\n resizeObserver?.disconnect();\n ipcRenderer.removeListener(AI_READ_ACTIVITY_CHANNEL, onActivity);\n for (const requestId of activeRequests.current.keys()) {\n void ipcRenderer.invoke(AI_CANCEL_CHANNEL, requestId).catch(() => {});\n }\n activeRequests.current.clear();\n window.clearInterval(timer);\n observer.disconnect();\n window.removeEventListener(\"power-ai-open\", updateAndOpen);\n };\n }, []);\n useEffect(() => {\n setLauncherHidden(false);\n const onScroll = (event: Event) => {\n const target = event.target;\n if (!(target instanceof HTMLElement) || target.closest('.power-ai-panel, .Sidebar, [role=\"navigation\"], aside'))\n return;\n if (!target.closest('.ItemListLayout, .KubeObjectListLayout, main, [role=\"main\"]')) return;\n if (target.scrollHeight <= target.clientHeight || target.clientHeight <= 0) return;\n setLauncherHidden(target.scrollTop > 0 && target.scrollHeight - target.clientHeight - target.scrollTop <= 16);\n };\n document.addEventListener(\"scroll\", onScroll, true);\n return () => document.removeEventListener(\"scroll\", onScroll, true);\n }, [context.screen]);\n useEffect(() => {\n if (!open) return;\n const onEscape = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\" || hasAiOverlay()) return;\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n if (!dismissSuggestions.current()) setOpen(false);\n };\n window.addEventListener(\"keydown\", onEscape, true);\n return () => window.removeEventListener(\"keydown\", onEscape, true);\n }, [open]);\n useEffect(() => {\n if (!open || pinned) return;\n const onOutsideClick = (event: MouseEvent) => {\n const target = event.target;\n if (\n !(target instanceof Element) ||\n target.closest(\n \".power-ai-panel, .power-ai-launcher, .power-ai-overview-actions, [data-freelens-power-ai-overlay]\",\n )\n )\n return;\n setOpen(false);\n };\n document.addEventListener(\"click\", onOutsideClick, true);\n return () => document.removeEventListener(\"click\", onOutsideClick, true);\n }, [open, pinned]);\n useEffect(() => {\n const heldKeys = new Set<string>();\n let shiftDownAt: number | undefined;\n let lastTapAt: number | undefined;\n const reset = () => {\n shiftDownAt = undefined;\n lastTapAt = undefined;\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \"Shift\") heldKeys.add(event.code || event.key);\n if (\n event.key !== \"Shift\" ||\n event.repeat ||\n event.isComposing ||\n event.keyCode === 229 ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n heldKeys.size > 0 ||\n shiftDownAt !== undefined\n ) {\n reset();\n return;\n }\n shiftDownAt = performance.now();\n };\n const onKeyUp = (event: KeyboardEvent) => {\n if (event.key === \"Meta\") {\n // macOS can omit keyup events for keys released while [Meta] is held\n heldKeys.clear();\n reset();\n return;\n }\n heldKeys.delete(event.code || event.key);\n const now = performance.now();\n if (\n event.key !== \"Shift\" ||\n shiftDownAt === undefined ||\n now - shiftDownAt > 400 ||\n event.isComposing ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n !preferences.enabled ||\n !isClusterDocument() ||\n hasAiOverlay()\n ) {\n reset();\n return;\n }\n shiftDownAt = undefined;\n if (lastTapAt === undefined || now - lastTapAt > 400) {\n lastTapAt = now;\n return;\n }\n reset();\n setContext(readAiContext());\n setOpen((value) => !value);\n };\n window.addEventListener(\"keydown\", onKeyDown, true);\n window.addEventListener(\"keyup\", onKeyUp, true);\n const onBlur = () => {\n heldKeys.clear();\n reset();\n };\n window.addEventListener(\"blur\", onBlur);\n return () => {\n window.removeEventListener(\"keydown\", onKeyDown, true);\n window.removeEventListener(\"keyup\", onKeyUp, true);\n window.removeEventListener(\"blur\", onBlur);\n };\n }, [preferences, isClusterDocument]);\n const availablePanelWidth = Math.max(1, viewportWidth - Math.max(0, launcherLeft - 16));\n const panelWidth = clampAiPanelWidth(preferences.chatPanelWidth ?? DEFAULT_AI_PANEL_WIDTH, availablePanelWidth);\n const shortcutLabel = \"Shift, Shift\";\n const key = context.clusterId ?? \"global\";\n const messages = preferences.conversations[key] ?? [];\n const busy = pending.includes(key);\n const readActivity = activity.key === key ? activity.reads : [];\n useEffect(() => {\n const element = messagesElement.current;\n if (element && following.current) element.scrollTop = element.scrollHeight;\n }, [messages.length, busy, open, key]);\n useEffect(() => {\n following.current = true;\n const element = messagesElement.current;\n if (element && open) element.scrollTop = element.scrollHeight;\n }, [open, key]);\n useEffect(() => {\n if (!terminalAttachment) return;\n const update = () => {\n if (activeAiTerminal(terminalAttachment.clusterId) !== terminalAttachment.terminalId)\n setTerminalAttachment(undefined);\n };\n update();\n const timer = window.setInterval(update, 500);\n const observer = new MutationObserver(update);\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"class\", \"style\", \"hidden\", \"aria-hidden\", \"data-testid\"],\n });\n return () => {\n window.clearInterval(timer);\n observer.disconnect();\n };\n }, [terminalAttachment, context.clusterId]);\n if (!preferences.enabled || !isClusterDocument() || coveredByOverlay) return null;\n const send = async (starter?: string) => {\n const question = expandAiShortcut(\n (starter ?? draft).trim(),\n AiShortcutsStore.getInstanceOrCreate<AiShortcutsStore>().shortcuts,\n );\n if (!question || busy) return;\n if (question.length > 20_000) {\n setError(\"Message is too long. Please keep it under 20,000 characters.\");\n return;\n }\n const requestContext = attachedAiContext(readAiContext());\n if ((requestContext.clusterId ?? \"global\") !== key) {\n setContext(requestContext);\n return;\n }\n const terminalSnapshot =\n terminalAttachment?.clusterId === requestContext.clusterId\n ? captureAiTerminal(requestContext.clusterId, terminalAttachment?.terminalId)\n : undefined;\n if (terminalAttachment && !terminalSnapshot) {\n setTerminalAttachment(undefined);\n setError(\"The attached terminal changed or is unavailable. Attach it again before sending.\");\n return;\n }\n setTerminalAttachment(undefined);\n following.current = true;\n const next: AiMessage[] = [...messages, { role: \"user\", text: question }];\n preferences.setMessages(key, next);\n setDraft(\"\");\n setError(\"\");\n setStopped((keys) => keys.filter((entry) => entry !== key));\n setActivity({ key, reads: [] });\n setPending((keys) => [...keys, key]);\n const provider = preferences.provider;\n const requestId = crypto.randomUUID();\n activeRequests.current.set(requestId, key);\n try {\n const response = await ipcRenderer.invoke(AI_CHAT_CHANNEL, {\n requestId,\n messages: next.slice(-80).reduceRight<AiMessage[]>((tail, message) => {\n if (tail.reduce((length, item) => length + item.text.length, 0) + message.text.length < 100_000)\n tail.unshift({ role: message.role, text: message.text });\n return tail;\n }, []),\n context: requestContext,\n ...(terminalSnapshot ? { terminalSnapshot } : {}),\n systemPrompt: [preferences.systemPrompt, requestContext.clusterId ? preferences.clusterPrompt : \"\"]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n model: preferences.model,\n speed: preferences.speed,\n reasoningEffort: preferences.reasoningEffort,\n });\n if (activeRequests.current.get(requestId) !== key) return;\n if (!response || typeof response.text !== \"string\") throw new Error(\"Invalid response\");\n setActivity({\n key,\n reads: Array.isArray(response.reads)\n ? response.reads\n .filter(\n (read: AiReadActivity) =>\n [\"pods\", \"nodes\", \"resources\", \"logs\"].includes(read?.method) &&\n [\"ok\", \"unavailable\"].includes(read?.status),\n )\n .slice(0, 6)\n : [],\n });\n preferences.setMessages(key, [\n ...next,\n {\n role: \"assistant\",\n text: response.text,\n provider: response.provider === \"claude\" ? \"claude\" : provider,\n references: normalizeAiReferences(response.references),\n },\n ]);\n } catch (failure) {\n if (activeRequests.current.get(requestId) !== key) return;\n const code = String(failure).match(/FREELENS_AI_([A-Z_]+)/)?.[1];\n const messages: Record<string, string> = {\n READ_LIMIT: \"The assistant reached the read limit. Try a more specific question.\",\n TIMEOUT: \"The request timed out. Please try again.\",\n INVALID_REPLY: \"The assistant returned an incomplete reply. Please try again.\",\n CLI_FAILURE: \"The selected CLI request failed. Check your model access or try again.\",\n CANCELLED: \"The request was canceled.\",\n UNSAFE_POLICY:\n \"Claude managed policy cannot be safely isolated. Use Codex or ask your administrator to disable managed hooks and command helpers.\",\n INPUT_LIMIT: \"The request is too large. Start a new chat or shorten the message.\",\n };\n setError(\n (code && messages[code]) ||\n \"Unable to complete the request. Check that the selected CLI is installed and signed in, then try again.\",\n );\n } finally {\n activeRequests.current.delete(requestId);\n setPending((keys) => keys.filter((entry) => entry !== key));\n }\n };\n const stopResponse = () => {\n const requestId = [...activeRequests.current].find(([, requestKey]) => requestKey === key)?.[0];\n if (!requestId) return;\n activeRequests.current.delete(requestId);\n setStopped((keys) => [...keys.filter((entry) => entry !== key), key]);\n setActivity({ key, reads: [] });\n setError(\"\");\n void ipcRenderer.invoke(AI_CANCEL_CHANNEL, requestId).catch(() => {});\n };\n clusterReview.current = () => {\n const currentKey = readAiContext().clusterId;\n if (!currentKey || currentKey !== key || preferences.conversations[currentKey]?.length) return;\n void send(\n preferences.clusterPrompt.trim() ||\n \"Review this cluster using read-only queries and summarize its health and useful next steps.\",\n );\n };\n return (\n <>\n <style>{styles}</style>\n {!open && (\n <button\n type=\"button\"\n className={`power-ai-launcher${launcherHidden ? \" power-ai-launcher-hidden\" : \"\"}`}\n aria-hidden={launcherHidden || undefined}\n tabIndex={launcherHidden ? -1 : 0}\n style={{\n bottom: launcherBottom,\n left: resourceDetailsOpen ? launcherLeft : \"auto\",\n right: resourceDetailsOpen ? \"auto\" : 16,\n }}\n onClick={() => setOpen(true)}\n aria-label=\"Open AI assistant\"\n title={`Open AI assistant (${shortcutLabel})`}\n >\n <span aria-hidden=\"true\">\n <AiIcon material=\"chat_bubble_outline\" size={16} />\n </span>{\" \"}\n AI\n </button>\n )}\n {open && (\n <aside\n className=\"power-ai-panel\"\n aria-label=\"AI assistant\"\n style={{ \"--power-ai-font-size\": `${preferences.chatFontSize ?? 14}px`, width: panelWidth } as CSSProperties}\n >\n <AiResizeHandle\n width={panelWidth}\n available={availablePanelWidth}\n onChange={(width) => preferences.setChatPanelWidth(width)}\n />\n <header>\n <strong className=\"power-ai-title\">\n <span className=\"power-ai-brand\" title=\"AI assistant\">\n <AiIcon material=\"auto_awesome\" size={18} /> AI\n </span>{\" \"}\n Assistant\n </strong>\n <button\n type=\"button\"\n disabled={busy}\n aria-label=\"New chat\"\n title=\"Clear this conversation and start a new chat\"\n onClick={() => {\n setTerminalAttachment(undefined);\n preferences.setMessages(key, []);\n setStopped((keys) => keys.filter((entry) => entry !== key));\n setActivity({ key, reads: [] });\n setError(\"\");\n }}\n >\n <AiIcon material=\"add_comment\" size={16} /> New chat\n </button>\n <button\n type=\"button\"\n className=\"power-ai-pin\"\n aria-label=\"Pin AI assistant\"\n aria-pressed={pinned}\n title={pinned ? \"Unpin to close when clicking outside\" : \"Pin to keep the assistant open\"}\n onClick={() => setPinned((value) => !value)}\n >\n <AiIcon material=\"push_pin\" size={18} />\n </button>\n <button\n type=\"button\"\n onPointerDown={(event) => event.stopPropagation()}\n onMouseDown={(event) => event.stopPropagation()}\n onClick={(event) => {\n event.stopPropagation();\n setOpen(false);\n }}\n className=\"power-ai-close\"\n aria-label=\"Close AI assistant\"\n title=\"Close AI assistant\"\n >\n <span aria-hidden=\"true\">\n <AiIcon material=\"close\" size={18} />\n </span>\n </button>\n </header>\n <div className=\"power-ai-context\">\n {context.clusterId ? \"Cluster conversation\" : \"General conversation\"} · {context.screen}\n {context.resource && ` · ${context.resource.kind}/${context.resource.name}`}\n <br />\n Only screen and resource metadata are attached automatically.\n </div>\n <div\n className=\"power-ai-messages\"\n onScroll={(event) => {\n const element = event.currentTarget;\n following.current = element.scrollHeight - element.scrollTop - element.clientHeight < 48;\n }}\n aria-live=\"polite\"\n ref={messagesElement}\n >\n {messages.length === 0 && (\n <div className=\"power-ai-starters\">\n <p style={{ marginBottom: 12 }}>Ask about this screen or your cluster:</p>\n <AiStarterPrompts\n disabled={busy}\n onSelect={(prompt) => {\n void send(prompt);\n }}\n />\n </div>\n )}\n {messages.map((message, index) => (\n <div className={`power-ai-message power-ai-message-${message.role}`} key={index}>\n <strong>\n {message.role === \"user\" ? (\n <span title=\"You\">\n <AiIcon material=\"person_outline\" size={16} />\n </span>\n ) : (\n <AiProviderIcon provider={message.provider === \"claude\" ? \"claude\" : \"codex\"} />\n )}\n {message.role === \"user\" ? \"You\" : message.provider === \"claude\" ? \"Claude\" : \"Codex\"}\n {message.role === \"assistant\" && <AiCopyAnswer text={message.text} />}\n </strong>\n <AiMessageContent text={message.text} />\n {message.role === \"assistant\" && context.clusterId && (\n <AiResourceReferences\n clusterId={context.clusterId}\n references={message.references}\n text={message.text}\n onOpened={() => setOpen(false)}\n />\n )}\n </div>\n ))}\n {readActivity.length > 0 && (\n <div\n className=\"power-ai-read-activity\"\n style={{ fontSize: 11, color: \"var(--textColorSecondary)\", margin: \"8px 16px\" }}\n >\n {readActivity.map((read, index) => (\n <span\n key={index}\n title={`${read.method} · ${read.status === \"reading\" ? \"reading\" : read.status === \"ok\" ? \"read\" : \"unavailable\"}`}\n data-method={read.method}\n data-status={read.status}\n style={{ marginRight: 10 }}\n >\n <AiIcon\n material={\n read.status === \"reading\"\n ? \"sync\"\n : read.status === \"ok\"\n ? \"check_circle_outline\"\n : \"info_outline\"\n }\n size={13}\n />{\" \"}\n {read.method} ·{\" \"}\n {read.status === \"reading\" ? \"reading\" : read.status === \"ok\" ? \"read\" : \"unavailable\"}\n </span>\n ))}\n </div>\n )}\n {busy && (\n <p className=\"power-ai-thinking\" role=\"status\">\n {stopped.includes(key) ? \"Stopping response\" : \"Thinking\"}\n <span className=\"power-ai-dots\" aria-hidden=\"true\">\n <span>.</span>\n <span>.</span>\n <span>.</span>\n </span>\n </p>\n )}\n {!busy && stopped.includes(key) && (\n <p className=\"power-ai-cancellation\" role=\"status\">\n Response stopped{\" \"}\n <button\n type=\"button\"\n aria-label=\"Dismiss cancellation\"\n className=\"power-ai-dismiss\"\n title=\"Dismiss\"\n onClick={() => setStopped((keys) => keys.filter((entry) => entry !== key))}\n >\n <AiIcon material=\"close\" size={14} />\n </button>\n </p>\n )}\n {error && <p role=\"alert\">{error}</p>}\n </div>\n <form\n onSubmit={(event) => {\n event.preventDefault();\n void send();\n }}\n >\n {suggestions.length > 0 && (\n <div\n className=\"power-ai-autocomplete\"\n role=\"listbox\"\n id=\"power-ai-commands\"\n aria-label=\"Prompt shortcuts\"\n >\n {suggestions.map((shortcut, index) => (\n <button\n type=\"button\"\n role=\"option\"\n id={`power-ai-command-${index}`}\n aria-selected={index === suggestionIndex % suggestions.length}\n key={shortcut.id}\n title={`Insert /${shortcut.command}: ${shortcut.label}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => selectSuggestion(index)}\n >\n <span>/{shortcut.command}</span>\n <span>{shortcut.label}</span>\n </button>\n ))}\n </div>\n )}\n <AiContextPreview context={attachedAiContext(context)} />\n <AiTerminalContext\n clusterId={context.clusterId}\n attachment={terminalAttachment}\n onChange={setTerminalAttachment}\n disabled={busy}\n />\n <textarea\n ref={composer}\n aria-controls={suggestions.length ? \"power-ai-commands\" : undefined}\n aria-expanded={suggestions.length > 0}\n aria-activedescendant={\n suggestions.length ? `power-ai-command-${suggestionIndex % suggestions.length}` : undefined\n }\n autoFocus\n aria-label=\"Message\"\n placeholder=\"Ask about this cluster…\"\n onKeyDown={(event) => {\n if (event.nativeEvent.isComposing || event.keyCode === 229) return;\n if (suggestions.length && !event.shiftKey) {\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n setSuggestionIndex(\n (index) =>\n (index + (event.key === \"ArrowDown\" ? 1 : suggestions.length - 1)) % suggestions.length,\n );\n return;\n }\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n event.preventDefault();\n selectSuggestion(suggestionIndex % suggestions.length);\n return;\n }\n }\n if (\n event.key === \"Enter\" &&\n !event.shiftKey &&\n !event.nativeEvent.isComposing &&\n event.keyCode !== 229\n ) {\n event.preventDefault();\n if (!busy) void send();\n }\n }}\n value={draft}\n onChange={(event) => {\n setDraft(event.target.value);\n setSuggestionIndex(0);\n setDismissedDraft(undefined);\n }}\n disabled={busy}\n />\n <div className=\"power-ai-composer-footer\">\n <span>Enter to send · Shift+Enter for newline</span>\n {busy ? (\n <button\n type=\"button\"\n aria-label=\"Stop response\"\n disabled={stopped.includes(key)}\n onClick={stopResponse}\n >\n <AiIcon material=\"stop\" size={16} /> Stop\n </button>\n ) : (\n <button type=\"submit\" disabled={!draft.trim()} aria-label=\"Send\">\n <AiIcon material=\"send\" size={16} />\n </button>\n )}\n </div>\n </form>\n </aside>\n )}\n </>\n );\n});\n\nexport function startAiChat(isClusterDocument: () => boolean = isAiClusterDocument): () => void {\n const container = document.createElement(\"div\");\n container.dataset.freelensPowerAi = \"\";\n document.body.append(container);\n let mounted = false;\n let overviewActions: HTMLDivElement | undefined;\n let overviewIcon: HTMLSpanElement | undefined;\n let overviewLabel: HTMLSpanElement | undefined;\n let overviewResize: ResizeObserver | undefined;\n const updateOverviewLabel = () => {\n const overview = overviewActions?.nextElementSibling;\n const compact = Boolean(overview?.querySelector(\"[data-freelens-power-monitoring]\") && overview.clientWidth > 960);\n const label = compact ? \"Ask AI\" : \"Ask about cluster\";\n if (overviewLabel && overviewLabel.textContent !== label) overviewLabel.textContent = label;\n overviewActions?.querySelector(\"button\")?.setAttribute(\"aria-label\", compact ? \"Ask AI about cluster\" : label);\n };\n const removeOverview = () => {\n overviewResize?.disconnect();\n overviewResize = undefined;\n if (overviewIcon) ReactDOM.unmountComponentAtNode(overviewIcon);\n overviewIcon = undefined;\n overviewLabel = undefined;\n overviewActions?.remove();\n overviewActions = undefined;\n };\n const preferences = AiPreferencesStore.getInstanceOrCreate<AiPreferencesStore>();\n const reconcile = () => {\n const overview =\n preferences.enabled &&\n isClusterDocument() &&\n Renderer.Catalog.activeCluster.get() &&\n document.querySelector('[data-testid=\"cluster-overview-page\"]');\n if (!overview) {\n removeOverview();\n return;\n }\n if (overviewActions?.isConnected && overviewActions.nextElementSibling === overview) {\n updateOverviewLabel();\n return;\n }\n removeOverview();\n overviewActions = document.createElement(\"div\");\n overviewActions.className = \"power-ai-overview-actions\";\n const overviewButton = document.createElement(\"button\");\n overviewButton.type = \"button\";\n overviewButton.setAttribute(\"aria-label\", \"Ask about cluster\");\n overviewButton.title = \"Open the AI assistant to ask about this cluster\";\n overviewIcon = document.createElement(\"span\");\n overviewIcon.setAttribute(\"aria-hidden\", \"true\");\n overviewLabel = document.createElement(\"span\");\n overviewButton.append(overviewIcon, overviewLabel);\n overviewButton.onclick = () => window.dispatchEvent(new Event(\"power-ai-open\"));\n overviewActions.append(overviewButton);\n overview.before(overviewActions);\n updateOverviewLabel();\n if (typeof ResizeObserver !== \"undefined\") {\n overviewResize = new ResizeObserver(updateOverviewLabel);\n overviewResize.observe(overview);\n }\n ReactDOM.render(<AiIcon material=\"auto_awesome\" size={16} />, overviewIcon);\n };\n const observer = new MutationObserver(reconcile);\n const stop = autorun(() => {\n if (preferences.enabled && !mounted) {\n observer.observe(document.body, { childList: true, subtree: true });\n mounted = true;\n ReactDOM.render(<AiChat isClusterDocument={isClusterDocument} />, container);\n } else if (!preferences.enabled && mounted) {\n observer.disconnect();\n ReactDOM.unmountComponentAtNode(container);\n mounted = false;\n }\n reconcile();\n });\n return () => {\n stop();\n observer.disconnect();\n removeOverview();\n ReactDOM.unmountComponentAtNode(container);\n container.remove();\n };\n}\n"],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@ function startAppearanceOverride() {
|
|
|
13
13
|
style.textContent = `${color === "default" ? "" : `
|
|
14
14
|
:root { --primary: ${color} !important; --buttonPrimaryBackground: ${color} !important; --menuSelectedOptionBgc: ${color} !important; --select-option-focused-bgc: color-mix(in srgb, ${color} 24%, var(--contentColor)) !important; --icon-focus-color: ${color} !important; }
|
|
15
15
|
:root .Checkbox, :root .Drawer .drawer-title, :root .DrawerParamToggler .param-link { --blue: var(--primary); }
|
|
16
|
+
:root [role="treeitem"][class*="catalog-tree-module__selected--"] { --blue: var(--primary); }
|
|
16
17
|
:root .Select:not(.Select--is-disabled) .Select__control--is-focused:not(.Select__control--is-disabled) { border-color: ${color} !important; box-shadow: 0 0 0 1px ${color} !important; }
|
|
17
18
|
:root .Select__option--is-selected { background: var(--primary) !important; color: var(--textColorAccent) !important; }
|
|
18
19
|
:root .NamespaceSelectMenu .Select__option { margin-block: 2px; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appearance.js","names":[],"sources":["../../src/renderer/appearance.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\nimport { reaction } from \"mobx\";\nimport { AppearancePreferencesStore, isAccentSelection } from \"../common/store/appearance-preferences-store\";\n\nexport function startAppearanceOverride(): () => void {\n const preferences = AppearancePreferencesStore.getInstanceOrCreate<AppearancePreferencesStore>();\n const style = document.createElement(\"style\");\n style.dataset.freelensPower = \"accent-color\";\n\n const stop = reaction(\n () => [preferences.enabled, preferences.accentColor] as const,\n ([enabled, color]) => {\n if (!enabled || !isAccentSelection(color)) {\n style.remove();\n return;\n }\n\n // [!important] takes precedence over the host theme's inline variables\n const accent =\n color === \"default\"\n ? \"\"\n : `\n :root { --primary: ${color} !important; --buttonPrimaryBackground: ${color} !important; --menuSelectedOptionBgc: ${color} !important; --select-option-focused-bgc: color-mix(in srgb, ${color} 24%, var(--contentColor)) !important; --icon-focus-color: ${color} !important; }\n :root .Checkbox, :root .Drawer .drawer-title, :root .DrawerParamToggler .param-link { --blue: var(--primary); }\n :root .Select:not(.Select--is-disabled) .Select__control--is-focused:not(.Select__control--is-disabled) { border-color: ${color} !important; box-shadow: 0 0 0 1px ${color} !important; }\n :root .Select__option--is-selected { background: var(--primary) !important; color: var(--textColorAccent) !important; }\n :root .NamespaceSelectMenu .Select__option { margin-block: 2px; }\n :root .NamespaceSelectMenu .Select__option--is-selected { background: color-mix(in srgb, var(--primary) 10%, var(--contentColor)) !important; color: var(--textColorAccent) !important; }\n :root .NamespaceSelectMenu .Select__option--is-selected.Select__option--is-focused { background: color-mix(in srgb, var(--primary) 24%, var(--contentColor)) !important; }\n :root .NamespaceSelectMenu .Select__option--is-selected .Icon { color: var(--primary); }\n :root a.link { color: var(--primary); }\n .Welcome [data-testid=\"no-welcome-banners-icon\"] svg path[fill=\"#23a49c\"] { fill: var(--primary); }\n `;\n style.textContent = `${accent}\\ninput[role=\"switch\"] { --track-color-active: var(--primary) !important; }`;\n\n if (!style.isConnected) {\n document.head.append(style);\n }\n },\n { fireImmediately: true },\n );\n\n return () => {\n stop();\n style.remove();\n };\n}\n"],"mappings":";;;AAIA,SAAgB,0BAAsC;CACpD,MAAM,cAAc,qCAAA,2BAA2B,oBAAgD;CAC/F,MAAM,QAAQ,SAAS,cAAc,OAAO;CAC5C,MAAM,QAAQ,gBAAgB;CAE9B,MAAM,OAAO,8BAAA,eACL,CAAC,YAAY,SAAS,YAAY,WAAW,IAClD,CAAC,SAAS,WAAW;EACpB,IAAI,CAAC,WAAW,CAAC,qCAAA,kBAAkB,KAAK,GAAG;GACzC,MAAM,OAAO;GACb;EACF;
|
|
1
|
+
{"version":3,"file":"appearance.js","names":[],"sources":["../../src/renderer/appearance.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\nimport { reaction } from \"mobx\";\nimport { AppearancePreferencesStore, isAccentSelection } from \"../common/store/appearance-preferences-store\";\n\nexport function startAppearanceOverride(): () => void {\n const preferences = AppearancePreferencesStore.getInstanceOrCreate<AppearancePreferencesStore>();\n const style = document.createElement(\"style\");\n style.dataset.freelensPower = \"accent-color\";\n\n const stop = reaction(\n () => [preferences.enabled, preferences.accentColor] as const,\n ([enabled, color]) => {\n if (!enabled || !isAccentSelection(color)) {\n style.remove();\n return;\n }\n\n // [!important] takes precedence over the host theme's inline variables\n const accent =\n color === \"default\"\n ? \"\"\n : `\n :root { --primary: ${color} !important; --buttonPrimaryBackground: ${color} !important; --menuSelectedOptionBgc: ${color} !important; --select-option-focused-bgc: color-mix(in srgb, ${color} 24%, var(--contentColor)) !important; --icon-focus-color: ${color} !important; }\n :root .Checkbox, :root .Drawer .drawer-title, :root .DrawerParamToggler .param-link { --blue: var(--primary); }\n :root [role=\"treeitem\"][class*=\"catalog-tree-module__selected--\"] { --blue: var(--primary); }\n :root .Select:not(.Select--is-disabled) .Select__control--is-focused:not(.Select__control--is-disabled) { border-color: ${color} !important; box-shadow: 0 0 0 1px ${color} !important; }\n :root .Select__option--is-selected { background: var(--primary) !important; color: var(--textColorAccent) !important; }\n :root .NamespaceSelectMenu .Select__option { margin-block: 2px; }\n :root .NamespaceSelectMenu .Select__option--is-selected { background: color-mix(in srgb, var(--primary) 10%, var(--contentColor)) !important; color: var(--textColorAccent) !important; }\n :root .NamespaceSelectMenu .Select__option--is-selected.Select__option--is-focused { background: color-mix(in srgb, var(--primary) 24%, var(--contentColor)) !important; }\n :root .NamespaceSelectMenu .Select__option--is-selected .Icon { color: var(--primary); }\n :root a.link { color: var(--primary); }\n .Welcome [data-testid=\"no-welcome-banners-icon\"] svg path[fill=\"#23a49c\"] { fill: var(--primary); }\n `;\n style.textContent = `${accent}\\ninput[role=\"switch\"] { --track-color-active: var(--primary) !important; }`;\n\n if (!style.isConnected) {\n document.head.append(style);\n }\n },\n { fireImmediately: true },\n );\n\n return () => {\n stop();\n style.remove();\n };\n}\n"],"mappings":";;;AAIA,SAAgB,0BAAsC;CACpD,MAAM,cAAc,qCAAA,2BAA2B,oBAAgD;CAC/F,MAAM,QAAQ,SAAS,cAAc,OAAO;CAC5C,MAAM,QAAQ,gBAAgB;CAE9B,MAAM,OAAO,8BAAA,eACL,CAAC,YAAY,SAAS,YAAY,WAAW,IAClD,CAAC,SAAS,WAAW;EACpB,IAAI,CAAC,WAAW,CAAC,qCAAA,kBAAkB,KAAK,GAAG;GACzC,MAAM,OAAO;GACb;EACF;EAmBA,MAAM,cAAc,GAflB,UAAU,YACN,KACA;6BACiB,MAAM,0CAA0C,MAAM,wCAAwC,MAAM,+DAA+D,MAAM,6DAA6D,MAAM;;;kIAGvI,MAAM,qCAAqC,MAAM;;;;;;;;QAS/I;EAE9B,IAAI,CAAC,MAAM,aACT,SAAS,KAAK,OAAO,KAAK;CAE9B,GACA,EAAE,iBAAiB,KAAK,CAC1B;CAEA,aAAa;EACX,KAAK;EACL,MAAM,OAAO;CACf;AACF"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
const require_appearance_preferences_store = require("./src/common/store/appearance-preferences-store.js");
|
|
2
|
+
const require__global_external_react = require("./_virtual/_global-external_react.js");
|
|
3
|
+
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
4
|
+
//#region src/renderer/cluster-icon-colors.tsx
|
|
5
|
+
var MATCHING_ICON_COLORS = [
|
|
6
|
+
{
|
|
7
|
+
name: "Lavender",
|
|
8
|
+
color: "#b49aff"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: "Sky",
|
|
12
|
+
color: "#64c9ff"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: "Mint",
|
|
16
|
+
color: "#6bdbb1"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: "Amber",
|
|
20
|
+
color: "#f2bd55"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "Coral",
|
|
24
|
+
color: "#ef7070"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "Rose",
|
|
28
|
+
color: "#e59cce"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "Slate",
|
|
32
|
+
color: "#9da7c2"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "Cyan",
|
|
36
|
+
color: "#78dce8"
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
var materialColors = [
|
|
40
|
+
["Red", "#f44336"],
|
|
41
|
+
["Pink", "#e91e63"],
|
|
42
|
+
["Purple", "#9c27b0"],
|
|
43
|
+
["Deep purple", "#673ab7"],
|
|
44
|
+
["Indigo", "#3f51b5"],
|
|
45
|
+
["Blue", "#2196f3"],
|
|
46
|
+
["Light blue", "#03a9f4"],
|
|
47
|
+
["Cyan", "#00bcd4"],
|
|
48
|
+
["Teal", "#009688"],
|
|
49
|
+
["Green", "#4caf50"],
|
|
50
|
+
["Light green", "#8bc34a"],
|
|
51
|
+
["Lime", "#cddc39"],
|
|
52
|
+
["Yellow", "#ffeb3b"],
|
|
53
|
+
["Amber", "#ffc107"],
|
|
54
|
+
["Orange", "#ff9800"],
|
|
55
|
+
["Deep orange", "#ff5722"],
|
|
56
|
+
["Brown", "#795548"],
|
|
57
|
+
["Grey", "#9e9e9e"],
|
|
58
|
+
["Blue grey", "#607d8b"]
|
|
59
|
+
].map(([name, color]) => ({
|
|
60
|
+
name,
|
|
61
|
+
color
|
|
62
|
+
}));
|
|
63
|
+
var materialHexes = new Set(materialColors.map(({ color }) => color));
|
|
64
|
+
var groups = [
|
|
65
|
+
{
|
|
66
|
+
name: "Power",
|
|
67
|
+
colors: MATCHING_ICON_COLORS
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "Freelens",
|
|
71
|
+
colors: require_appearance_preferences_store.ACCENT_COLOR_OPTIONS.filter(({ color }) => !materialHexes.has(color.toLowerCase())).map(({ label, color }) => ({
|
|
72
|
+
name: label,
|
|
73
|
+
color
|
|
74
|
+
}))
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "Material",
|
|
78
|
+
colors: materialColors
|
|
79
|
+
}
|
|
80
|
+
];
|
|
81
|
+
var styles = `
|
|
82
|
+
.power-icon-palette { position: relative; }
|
|
83
|
+
.power-icon-palette button { font: inherit; cursor: pointer; }
|
|
84
|
+
.power-icon-palette button:disabled { cursor: default; opacity: .5; }
|
|
85
|
+
.power-icon-palette button:focus-visible, .power-icon-palette input:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
|
|
86
|
+
.power-icon-palette-trigger { display: flex; align-items: center; gap: 9px; padding: 5px 7px; border: 1px solid var(--borderFaintColor); border-radius: 7px; background: var(--contentColor); color: var(--textColorSecondary); }
|
|
87
|
+
.power-icon-palette-trigger code { font: 11px var(--font-monospace,monospace); }
|
|
88
|
+
.power-icon-palette-well { width: 22px; height: 22px; border-radius: 5px; border: 1px solid rgb(255 255 255 / 15%); }
|
|
89
|
+
.power-icon-palette-panel { position: absolute; z-index: 4; right: 0; top: calc(100% + 7px); box-sizing: border-box; width: 280px; max-width: calc(100vw - 72px); padding: 14px; border: 1px solid var(--borderFaintColor); border-radius: 11px; background: var(--mainBackground); color: var(--textColorPrimary); box-shadow: 0 12px 36px rgb(0 0 0 / 35%); display: grid; gap: 14px; }
|
|
90
|
+
.power-icon-palette-heading { font-size: 11px; color: var(--textColorSecondary); margin-bottom: 8px; }
|
|
91
|
+
.power-icon-palette-grid { display: grid; grid-template-columns: repeat(8,minmax(0,1fr)); gap: 6px; }
|
|
92
|
+
.power-icon-palette-swatch { width: 100%; max-width: 23px; height: auto; aspect-ratio: 1; min-width: 0; padding: 0; border: 1px solid rgb(255 255 255 / 18%); border-radius: 6px; }
|
|
93
|
+
.power-icon-palette-swatch[aria-pressed=true] { outline: 2px solid var(--textColorPrimary); outline-offset: 2px; }
|
|
94
|
+
`;
|
|
95
|
+
function IconColorPicker({ label, value, onChange, disabled = false, onOpenChange }) {
|
|
96
|
+
const [open, setOpen] = require__global_external_react.useState(false);
|
|
97
|
+
const root = require__global_external_react.useRef(null);
|
|
98
|
+
const trigger = require__global_external_react.useRef(null);
|
|
99
|
+
const notify = require__global_external_react.useRef(onOpenChange);
|
|
100
|
+
notify.current = onOpenChange;
|
|
101
|
+
const changeOpen = (next) => {
|
|
102
|
+
notify.current?.(next);
|
|
103
|
+
setOpen(next);
|
|
104
|
+
};
|
|
105
|
+
require__global_external_react.useEffect(() => {
|
|
106
|
+
if (!open) return;
|
|
107
|
+
root.current?.querySelector(".power-icon-palette-swatch")?.focus();
|
|
108
|
+
const outside = (event) => {
|
|
109
|
+
if (event.target instanceof Node && !root.current?.contains(event.target)) changeOpen(false);
|
|
110
|
+
};
|
|
111
|
+
const escape = (event) => {
|
|
112
|
+
if (event.key !== "Escape") return;
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
event.stopImmediatePropagation();
|
|
115
|
+
changeOpen(false);
|
|
116
|
+
trigger.current?.focus();
|
|
117
|
+
};
|
|
118
|
+
document.addEventListener("pointerdown", outside, true);
|
|
119
|
+
document.addEventListener("keydown", escape, true);
|
|
120
|
+
return () => {
|
|
121
|
+
document.removeEventListener("pointerdown", outside, true);
|
|
122
|
+
document.removeEventListener("keydown", escape, true);
|
|
123
|
+
};
|
|
124
|
+
}, [open]);
|
|
125
|
+
require__global_external_react.useEffect(() => () => notify.current?.(false), []);
|
|
126
|
+
require__global_external_react.useEffect(() => {
|
|
127
|
+
if (disabled) changeOpen(false);
|
|
128
|
+
}, [disabled]);
|
|
129
|
+
const choose = (hex) => {
|
|
130
|
+
if (disabled || !/^#[\da-f]{6}$/i.test(hex)) return;
|
|
131
|
+
onChange(hex.toLowerCase());
|
|
132
|
+
changeOpen(false);
|
|
133
|
+
trigger.current?.focus();
|
|
134
|
+
};
|
|
135
|
+
return /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
136
|
+
className: "power-icon-palette",
|
|
137
|
+
ref: root,
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("style", { children: styles }),
|
|
140
|
+
/* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
141
|
+
ref: trigger,
|
|
142
|
+
type: "button",
|
|
143
|
+
className: "power-icon-palette-trigger",
|
|
144
|
+
"aria-label": label,
|
|
145
|
+
"aria-expanded": open,
|
|
146
|
+
disabled,
|
|
147
|
+
onClick: () => changeOpen(!open),
|
|
148
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx("code", { children: value }), /* @__PURE__ */ require_jsx_runtime.jsx("span", {
|
|
149
|
+
className: "power-icon-palette-well",
|
|
150
|
+
style: { backgroundColor: value },
|
|
151
|
+
"aria-hidden": "true"
|
|
152
|
+
})]
|
|
153
|
+
}),
|
|
154
|
+
open && /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
155
|
+
className: "power-icon-palette-panel",
|
|
156
|
+
role: "group",
|
|
157
|
+
"aria-label": `${label} palette`,
|
|
158
|
+
onBlur: (event) => {
|
|
159
|
+
if (event.relatedTarget instanceof Node && !root.current?.contains(event.relatedTarget)) changeOpen(false);
|
|
160
|
+
},
|
|
161
|
+
children: groups.map((group) => /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
162
|
+
role: "group",
|
|
163
|
+
"aria-label": group.name,
|
|
164
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
165
|
+
className: "power-icon-palette-heading",
|
|
166
|
+
children: group.name
|
|
167
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
168
|
+
className: "power-icon-palette-grid",
|
|
169
|
+
children: group.colors.map((color) => /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
170
|
+
type: "button",
|
|
171
|
+
className: "power-icon-palette-swatch",
|
|
172
|
+
style: { backgroundColor: color.color },
|
|
173
|
+
title: `${color.name} ${color.color}`,
|
|
174
|
+
"aria-label": `${group.name} ${color.name} ${color.color}`,
|
|
175
|
+
"aria-pressed": value.toLowerCase() === color.color,
|
|
176
|
+
onClick: () => choose(color.color)
|
|
177
|
+
}, color.name))
|
|
178
|
+
})]
|
|
179
|
+
}, group.name))
|
|
180
|
+
})
|
|
181
|
+
]
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
exports.IconColorPicker = IconColorPicker;
|
|
186
|
+
exports.MATCHING_ICON_COLORS = MATCHING_ICON_COLORS;
|
|
187
|
+
|
|
188
|
+
//# sourceMappingURL=cluster-icon-colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster-icon-colors.js","names":[],"sources":["../../src/renderer/cluster-icon-colors.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { ACCENT_COLOR_OPTIONS } from \"../common/store/appearance-preferences-store\";\n\nexport const MATCHING_ICON_COLORS = [\n { name: \"Lavender\", color: \"#b49aff\" },\n { name: \"Sky\", color: \"#64c9ff\" },\n { name: \"Mint\", color: \"#6bdbb1\" },\n { name: \"Amber\", color: \"#f2bd55\" },\n { name: \"Coral\", color: \"#ef7070\" },\n { name: \"Rose\", color: \"#e59cce\" },\n { name: \"Slate\", color: \"#9da7c2\" },\n { name: \"Cyan\", color: \"#78dce8\" },\n];\n\n// material design 2014 primary palette, shade [500]: https://m1.material.io/style/color.html\nconst materialColors = [\n [\"Red\", \"#f44336\"],\n [\"Pink\", \"#e91e63\"],\n [\"Purple\", \"#9c27b0\"],\n [\"Deep purple\", \"#673ab7\"],\n [\"Indigo\", \"#3f51b5\"],\n [\"Blue\", \"#2196f3\"],\n [\"Light blue\", \"#03a9f4\"],\n [\"Cyan\", \"#00bcd4\"],\n [\"Teal\", \"#009688\"],\n [\"Green\", \"#4caf50\"],\n [\"Light green\", \"#8bc34a\"],\n [\"Lime\", \"#cddc39\"],\n [\"Yellow\", \"#ffeb3b\"],\n [\"Amber\", \"#ffc107\"],\n [\"Orange\", \"#ff9800\"],\n [\"Deep orange\", \"#ff5722\"],\n [\"Brown\", \"#795548\"],\n [\"Grey\", \"#9e9e9e\"],\n [\"Blue grey\", \"#607d8b\"],\n].map(([name, color]) => ({ name, color }));\n\nconst materialHexes = new Set(materialColors.map(({ color }) => color));\n\nconst groups = [\n { name: \"Power\", colors: MATCHING_ICON_COLORS },\n {\n name: \"Freelens\",\n colors: ACCENT_COLOR_OPTIONS.filter(({ color }) => !materialHexes.has(color.toLowerCase())).map(\n ({ label, color }) => ({\n name: label,\n color,\n }),\n ),\n },\n { name: \"Material\", colors: materialColors },\n];\n\nconst styles = `\n.power-icon-palette { position: relative; }\n.power-icon-palette button { font: inherit; cursor: pointer; }\n.power-icon-palette button:disabled { cursor: default; opacity: .5; }\n.power-icon-palette button:focus-visible, .power-icon-palette input:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }\n.power-icon-palette-trigger { display: flex; align-items: center; gap: 9px; padding: 5px 7px; border: 1px solid var(--borderFaintColor); border-radius: 7px; background: var(--contentColor); color: var(--textColorSecondary); }\n.power-icon-palette-trigger code { font: 11px var(--font-monospace,monospace); }\n.power-icon-palette-well { width: 22px; height: 22px; border-radius: 5px; border: 1px solid rgb(255 255 255 / 15%); }\n.power-icon-palette-panel { position: absolute; z-index: 4; right: 0; top: calc(100% + 7px); box-sizing: border-box; width: 280px; max-width: calc(100vw - 72px); padding: 14px; border: 1px solid var(--borderFaintColor); border-radius: 11px; background: var(--mainBackground); color: var(--textColorPrimary); box-shadow: 0 12px 36px rgb(0 0 0 / 35%); display: grid; gap: 14px; }\n.power-icon-palette-heading { font-size: 11px; color: var(--textColorSecondary); margin-bottom: 8px; }\n.power-icon-palette-grid { display: grid; grid-template-columns: repeat(8,minmax(0,1fr)); gap: 6px; }\n.power-icon-palette-swatch { width: 100%; max-width: 23px; height: auto; aspect-ratio: 1; min-width: 0; padding: 0; border: 1px solid rgb(255 255 255 / 18%); border-radius: 6px; }\n.power-icon-palette-swatch[aria-pressed=true] { outline: 2px solid var(--textColorPrimary); outline-offset: 2px; }\n`;\n\nexport function IconColorPicker({\n label,\n value,\n onChange,\n disabled = false,\n onOpenChange,\n}: {\n label: string;\n value: string;\n onChange: (hex: string) => void;\n disabled?: boolean;\n onOpenChange?: (open: boolean) => void;\n}) {\n const [open, setOpen] = useState(false);\n const root = useRef<HTMLDivElement>(null);\n const trigger = useRef<HTMLButtonElement>(null);\n const notify = useRef(onOpenChange);\n notify.current = onOpenChange;\n const changeOpen = (next: boolean) => {\n notify.current?.(next);\n setOpen(next);\n };\n useEffect(() => {\n if (!open) return;\n root.current?.querySelector<HTMLButtonElement>(\".power-icon-palette-swatch\")?.focus();\n const outside = (event: PointerEvent) => {\n if (event.target instanceof Node && !root.current?.contains(event.target)) changeOpen(false);\n };\n const escape = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n event.stopImmediatePropagation();\n changeOpen(false);\n trigger.current?.focus();\n };\n document.addEventListener(\"pointerdown\", outside, true);\n document.addEventListener(\"keydown\", escape, true);\n return () => {\n document.removeEventListener(\"pointerdown\", outside, true);\n document.removeEventListener(\"keydown\", escape, true);\n };\n }, [open]);\n useEffect(() => () => notify.current?.(false), []);\n useEffect(() => {\n if (disabled) changeOpen(false);\n }, [disabled]);\n const choose = (hex: string) => {\n if (disabled || !/^#[\\da-f]{6}$/i.test(hex)) return;\n onChange(hex.toLowerCase());\n changeOpen(false);\n trigger.current?.focus();\n };\n return (\n <div className=\"power-icon-palette\" ref={root}>\n <style>{styles}</style>\n <button\n ref={trigger}\n type=\"button\"\n className=\"power-icon-palette-trigger\"\n aria-label={label}\n aria-expanded={open}\n disabled={disabled}\n onClick={() => changeOpen(!open)}\n >\n <code>{value}</code>\n <span className=\"power-icon-palette-well\" style={{ backgroundColor: value }} aria-hidden=\"true\" />\n </button>\n {open && (\n <div\n className=\"power-icon-palette-panel\"\n role=\"group\"\n aria-label={`${label} palette`}\n onBlur={(event) => {\n if (event.relatedTarget instanceof Node && !root.current?.contains(event.relatedTarget)) changeOpen(false);\n }}\n >\n {groups.map((group) => (\n <div key={group.name} role=\"group\" aria-label={group.name}>\n <div className=\"power-icon-palette-heading\">{group.name}</div>\n <div className=\"power-icon-palette-grid\">\n {group.colors.map((color) => (\n <button\n type=\"button\"\n key={color.name}\n className=\"power-icon-palette-swatch\"\n style={{ backgroundColor: color.color }}\n title={`${color.name} ${color.color}`}\n aria-label={`${group.name} ${color.name} ${color.color}`}\n aria-pressed={value.toLowerCase() === color.color}\n onClick={() => choose(color.color)}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|