@termix-ssh/plugin-sdk 1.0.11 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/PLUGIN-GUIDE.md +178 -54
  3. package/cli/commands/build.mjs +36 -22
  4. package/cli/commands/pack.mjs +12 -2
  5. package/cli/commands/validate.mjs +63 -3
  6. package/cli/lib/plugin-dir.mjs +11 -0
  7. package/cli/lib/tmxplug.mjs +9 -0
  8. package/dist/backend.d.ts +404 -0
  9. package/dist/capabilities.js +7 -0
  10. package/dist/db.js +1 -0
  11. package/dist/desktop.d.ts +0 -243
  12. package/dist/frontend.d.ts +175 -2
  13. package/dist/frontend.js +7 -0
  14. package/dist/host/PluginsTab-OXQQ7M4I.js +3266 -0
  15. package/dist/host/chunk-54KCK6IZ.js +3167 -0
  16. package/dist/host/chunk-CALNJCHN.js +10435 -0
  17. package/dist/host/{chunk-7RRTYD6B.js → chunk-CN5UBTBP.js} +1412 -14
  18. package/dist/host/{chunk-RLQBKJRK.js → chunk-ERGN4YW6.js} +9204 -11492
  19. package/dist/host/{chunk-LSWB3ZZV.js → chunk-T2PZWXFJ.js} +6 -1
  20. package/dist/host/chunk-YGYBM7SQ.js +58 -0
  21. package/dist/host/core-classes.json +1 -1
  22. package/dist/host/{linked-server-UCW74T2V.js → linked-server-5VFO4XQB.js} +2 -2
  23. package/dist/host/{rbac-api-6UYMFIFV.js → rbac-api-5YMBJAO5.js} +2 -2
  24. package/dist/host/testing-host.js +123 -57
  25. package/dist/host/types/src/types/onboarding.d.ts +0 -2
  26. package/dist/host/types/src/types/ui-types.d.ts +2 -1
  27. package/dist/host/types/src/ui/api/audit-log-api.d.ts +36 -0
  28. package/dist/host/types/src/ui/api/credentials-api.d.ts +0 -22
  29. package/dist/host/types/src/ui/api/host-defaults-api.d.ts +42 -0
  30. package/dist/host/types/src/ui/api/host-tags-api.d.ts +2 -0
  31. package/dist/host/types/src/ui/api/look-api.d.ts +40 -0
  32. package/dist/host/types/src/ui/api/open-tabs-api.d.ts +4 -0
  33. package/dist/host/types/src/ui/api/plugins-api.d.ts +30 -0
  34. package/dist/host/types/src/ui/api/private-endpoints-api.d.ts +6 -0
  35. package/dist/host/types/src/ui/api/settings-api.d.ts +0 -6
  36. package/dist/host/types/src/ui/api/ssh-host-management-api.d.ts +0 -28
  37. package/dist/host/types/src/ui/api/tls-api.d.ts +25 -0
  38. package/dist/host/types/src/ui/auth/ElectronLoginForm.d.ts +9 -0
  39. package/dist/host/types/src/ui/components/command.d.ts +78 -0
  40. package/dist/host/types/src/ui/components/folder-style.d.ts +16 -0
  41. package/dist/host/types/src/ui/components/theme-provider.d.ts +2 -1
  42. package/dist/host/types/src/ui/components/version-badge.d.ts +7 -0
  43. package/dist/host/types/src/ui/hooks/use-page-visible-interval.d.ts +10 -0
  44. package/dist/host/types/src/ui/lib/activity-types.d.ts +15 -0
  45. package/dist/host/types/src/ui/lib/app-version.d.ts +2 -0
  46. package/dist/host/types/src/ui/lib/apply-ui-preset.d.ts +19 -0
  47. package/dist/host/types/src/ui/lib/create-id.d.ts +2 -0
  48. package/dist/host/types/src/ui/lib/database-transfer-url.d.ts +8 -0
  49. package/dist/host/types/src/ui/lib/desktop-updates.d.ts +29 -0
  50. package/dist/host/types/src/ui/lib/host-connection-tabs.d.ts +14 -0
  51. package/dist/host/types/src/ui/lib/host-to-ssh-host.d.ts +4 -0
  52. package/dist/host/types/src/ui/lib/issue-url.d.ts +21 -0
  53. package/dist/host/types/src/ui/lib/local-adaptive-preferences.d.ts +9 -0
  54. package/dist/host/types/src/ui/lib/pane-nav-hotkey.d.ts +7 -0
  55. package/dist/host/types/src/ui/lib/plugin-i18n.d.ts +4 -3
  56. package/dist/host/types/src/ui/lib/role-label.d.ts +3 -0
  57. package/dist/host/types/src/ui/look/LookSettings.d.ts +8 -0
  58. package/dist/host/types/src/ui/look/layout-registry.d.ts +34 -0
  59. package/dist/host/types/src/ui/look/look-store.d.ts +29 -0
  60. package/dist/host/types/src/ui/look/resolve-look.d.ts +18 -0
  61. package/dist/host/types/src/ui/look/theme-css.d.ts +7 -0
  62. package/dist/host/types/src/ui/look/theme-registry.d.ts +41 -0
  63. package/dist/host/types/src/ui/look/use-look-theme.d.ts +12 -0
  64. package/dist/host/types/src/ui/main-axios.d.ts +2 -2
  65. package/dist/host/types/src/ui/manage/manage-requests.d.ts +34 -0
  66. package/dist/host/types/src/ui/onboarding/onboarding-registry.d.ts +3 -1
  67. package/dist/host/types/src/ui/plugin-host/loader.d.ts +2 -0
  68. package/dist/host/types/src/ui/plugin-host/scope.d.ts +6 -0
  69. package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +101 -0
  70. package/dist/host/types/src/ui/plugin-host/view-ownership.d.ts +1 -1
  71. package/dist/host/types/src/ui/plugins/PluginConsentPrompt.d.ts +20 -0
  72. package/dist/host/types/src/ui/plugins/PluginDetail.d.ts +7 -0
  73. package/dist/host/types/src/ui/plugins/PluginReleaseNotes.d.ts +14 -0
  74. package/dist/host/types/src/ui/plugins/PluginsTab.d.ts +1 -0
  75. package/dist/host/types/src/ui/plugins/RegistriesSection.d.ts +4 -0
  76. package/dist/host/types/src/ui/plugins/plugin-bits.d.ts +23 -0
  77. package/dist/host/types/src/ui/plugins/plugin-model.d.ts +136 -0
  78. package/dist/host/types/src/ui/plugins/use-plugins-manager.d.ts +78 -0
  79. package/dist/host/types/src/ui/settings/appearance/appearance-controls.d.ts +53 -0
  80. package/dist/host/types/src/ui/settings/sync/LinkServerDialog.d.ts +12 -0
  81. package/dist/host/types/src/ui/settings/sync/ProxySettingsFields.d.ts +15 -0
  82. package/dist/host/types/src/ui/settings/sync/saved-servers.d.ts +3 -0
  83. package/dist/host/types/src/ui/shell/controller/ShellControllerProvider.d.ts +20 -0
  84. package/dist/host/types/src/ui/shell/controller/plugin-shell.d.ts +7 -0
  85. package/dist/host/types/src/ui/shell/controller/shell-store.d.ts +4 -0
  86. package/dist/host/types/src/ui/shell/controller/types.d.ts +156 -0
  87. package/dist/host/types/src/ui/shell/controller/use-hosts.d.ts +10 -0
  88. package/dist/host/types/src/ui/shell/controller/use-regions.d.ts +5 -0
  89. package/dist/host/types/src/ui/shell/controller/use-shell-keybindings.d.ts +12 -0
  90. package/dist/host/types/src/ui/shell/controller/use-shell-lifecycle.d.ts +17 -0
  91. package/dist/host/types/src/ui/shell/controller/use-split.d.ts +21 -0
  92. package/dist/host/types/src/ui/shell/controller/use-tabs.d.ts +70 -0
  93. package/dist/host/types/src/ui/shell/controller/use-workspace-layout.d.ts +4 -0
  94. package/dist/host/types/src/ui/shell/reconnect-tabs.d.ts +6 -0
  95. package/dist/host/types/src/ui/shell/shell-layout.d.ts +46 -0
  96. package/dist/host/types/src/ui/shell/split/EmptyPanePicker.d.ts +32 -0
  97. package/dist/host/types/src/ui/shell/split/SplitDropOverlay.d.ts +9 -0
  98. package/dist/host/types/src/ui/shell/split/SplitLayoutMenu.d.ts +16 -0
  99. package/dist/host/types/src/ui/shell/split/SplitView.d.ts +31 -0
  100. package/dist/host/types/src/ui/shell/split/split-drag.d.ts +58 -0
  101. package/dist/host/types/src/ui/shell/split/split-presets.d.ts +28 -0
  102. package/dist/host/types/src/ui/shell/split/split-tabs.d.ts +95 -0
  103. package/dist/host/types/src/ui/shell/split/split-targets.d.ts +30 -0
  104. package/dist/host/types/src/ui/shell/split/split-tree.d.ts +89 -0
  105. package/dist/host/types/src/ui/shell/stage/TabStage.d.ts +9 -0
  106. package/dist/host/types/src/ui/shell/stage/tab-stage-store.d.ts +24 -0
  107. package/dist/host/types/src/ui/shell/tab-close-guards.d.ts +9 -0
  108. package/dist/host/types/src/ui/shell/tab-handles.d.ts +8 -0
  109. package/dist/host/types/src/ui/shell/tabUtils.d.ts +15 -0
  110. package/dist/host/types/src/ui/sidebar/AuthEnrollmentSections.d.ts +5 -0
  111. package/dist/host/types/src/ui/sidebar/HostManagerData.d.ts +4 -0
  112. package/dist/host/types/src/ui/sidebar/build-host-tree.d.ts +25 -0
  113. package/dist/host/types/src/ui/sidebar/host-contributions.d.ts +10 -0
  114. package/dist/host/ui.js +6045 -4055
  115. package/dist/host/{use-permissions-GYCBY2AU.js → use-permissions-ISEDRY3J.js} +2 -2
  116. package/dist/manifest.d.ts +50 -1
  117. package/dist/manifest.js +104 -1
  118. package/dist/ssh-keys.d.ts +29 -0
  119. package/dist/ssh-keys.js +85 -0
  120. package/dist/testing/setup.js +1 -0
  121. package/dist/testing.d.ts +32 -15
  122. package/dist/testing.js +218 -1
  123. package/dist/theme-css.d.ts +11 -0
  124. package/dist/theme-css.js +142 -0
  125. package/dist/vitest-preset.d.ts +18 -0
  126. package/dist/vitest-preset.js +14 -3
  127. package/package.json +5 -1
  128. package/schema/manifest.schema.json +121 -8
  129. package/tsconfig.plugin.json +1 -0
  130. package/dist/host/chunk-YC2MAKSP.js +0 -14
@@ -1,10 +1,15 @@
1
1
  const __termixNoGlob = () => ({});
2
2
  import {
3
3
  __export,
4
- define_import_meta_env_default
5
- } from "./chunk-YC2MAKSP.js";
4
+ define_import_meta_env_default,
5
+ init_define_import_meta_env
6
+ } from "./chunk-YGYBM7SQ.js";
7
+
8
+ // src/ui/lib/linked-server.ts
9
+ init_define_import_meta_env();
6
10
 
7
11
  // src/ui/lib/electron.ts
12
+ init_define_import_meta_env();
8
13
  function isElectron() {
9
14
  if (typeof window === "undefined") return false;
10
15
  const win = window;
@@ -20,12 +25,26 @@ function localBackendPort() {
20
25
  return typeof port === "number" && Number.isInteger(port) && port > 0 && port < 65536 ? port : DEFAULT_LOCAL_BACKEND_PORT;
21
26
  }
22
27
 
28
+ // src/ui/main-axios.ts
29
+ init_define_import_meta_env();
30
+
23
31
  // src/ui/lib/error-message.ts
32
+ init_define_import_meta_env();
24
33
  function getErrorMessage(error, fallback = "Unknown error") {
25
34
  return error instanceof Error ? error.message : fallback;
26
35
  }
27
36
 
37
+ // node_modules/axios/index.js
38
+ init_define_import_meta_env();
39
+
40
+ // node_modules/axios/lib/axios.js
41
+ init_define_import_meta_env();
42
+
43
+ // node_modules/axios/lib/utils.js
44
+ init_define_import_meta_env();
45
+
28
46
  // node_modules/axios/lib/helpers/bind.js
47
+ init_define_import_meta_env();
29
48
  function bind(fn, thisArg) {
30
49
  return function wrap() {
31
50
  return fn.apply(thisArg, arguments);
@@ -580,7 +599,26 @@ var utils_default = {
580
599
  isSafeIterable
581
600
  };
582
601
 
602
+ // node_modules/axios/lib/core/Axios.js
603
+ init_define_import_meta_env();
604
+
605
+ // node_modules/axios/lib/helpers/buildURL.js
606
+ init_define_import_meta_env();
607
+
608
+ // node_modules/axios/lib/helpers/AxiosURLSearchParams.js
609
+ init_define_import_meta_env();
610
+
611
+ // node_modules/axios/lib/helpers/toFormData.js
612
+ init_define_import_meta_env();
613
+
614
+ // node_modules/axios/lib/core/AxiosError.js
615
+ init_define_import_meta_env();
616
+
617
+ // node_modules/axios/lib/core/AxiosHeaders.js
618
+ init_define_import_meta_env();
619
+
583
620
  // node_modules/axios/lib/helpers/parseHeaders.js
621
+ init_define_import_meta_env();
584
622
  var ignoreDuplicateOf = utils_default.toObjectSet([
585
623
  "age",
586
624
  "authorization",
@@ -627,6 +665,7 @@ var parseHeaders_default = (rawHeaders) => {
627
665
  };
628
666
 
629
667
  // node_modules/axios/lib/helpers/sanitizeHeaderValue.js
668
+ init_define_import_meta_env();
630
669
  function trimSPorHTAB(str) {
631
670
  let start = 0;
632
671
  let end = str.length;
@@ -1160,6 +1199,7 @@ AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED = "ERR_FORM_DATA_DEPTH_EXCEEDED";
1160
1199
  var AxiosError_default = AxiosError;
1161
1200
 
1162
1201
  // node_modules/axios/lib/helpers/null.js
1202
+ init_define_import_meta_env();
1163
1203
  var null_default = null;
1164
1204
 
1165
1205
  // node_modules/axios/lib/helpers/toFormData.js
@@ -1370,6 +1410,7 @@ function buildURL(url, params, options) {
1370
1410
  }
1371
1411
 
1372
1412
  // node_modules/axios/lib/core/InterceptorManager.js
1413
+ init_define_import_meta_env();
1373
1414
  var $internals2 = /* @__PURE__ */ Symbol("internals");
1374
1415
  function countHandlers(handlers) {
1375
1416
  return handlers ? handlers.length : 0;
@@ -1507,7 +1548,17 @@ var InterceptorManager = class {
1507
1548
  };
1508
1549
  var InterceptorManager_default = InterceptorManager;
1509
1550
 
1551
+ // node_modules/axios/lib/core/dispatchRequest.js
1552
+ init_define_import_meta_env();
1553
+
1554
+ // node_modules/axios/lib/core/transformData.js
1555
+ init_define_import_meta_env();
1556
+
1557
+ // node_modules/axios/lib/defaults/index.js
1558
+ init_define_import_meta_env();
1559
+
1510
1560
  // node_modules/axios/lib/defaults/transitional.js
1561
+ init_define_import_meta_env();
1511
1562
  var transitional_default = {
1512
1563
  silentJSONParsing: true,
1513
1564
  forcedJSONParsing: true,
@@ -1517,13 +1568,25 @@ var transitional_default = {
1517
1568
  validateStatusUndefinedResolves: true
1518
1569
  };
1519
1570
 
1571
+ // node_modules/axios/lib/helpers/toURLEncodedForm.js
1572
+ init_define_import_meta_env();
1573
+
1574
+ // node_modules/axios/lib/platform/index.js
1575
+ init_define_import_meta_env();
1576
+
1577
+ // node_modules/axios/lib/platform/browser/index.js
1578
+ init_define_import_meta_env();
1579
+
1520
1580
  // node_modules/axios/lib/platform/browser/classes/URLSearchParams.js
1581
+ init_define_import_meta_env();
1521
1582
  var URLSearchParams_default = typeof URLSearchParams !== "undefined" ? URLSearchParams : AxiosURLSearchParams_default;
1522
1583
 
1523
1584
  // node_modules/axios/lib/platform/browser/classes/FormData.js
1585
+ init_define_import_meta_env();
1524
1586
  var FormData_default = typeof FormData !== "undefined" ? FormData : null;
1525
1587
 
1526
1588
  // node_modules/axios/lib/platform/browser/classes/Blob.js
1589
+ init_define_import_meta_env();
1527
1590
  var Blob_default = typeof Blob !== "undefined" ? Blob : null;
1528
1591
 
1529
1592
  // node_modules/axios/lib/platform/browser/index.js
@@ -1546,6 +1609,7 @@ __export(utils_exports, {
1546
1609
  navigator: () => _navigator,
1547
1610
  origin: () => origin
1548
1611
  });
1612
+ init_define_import_meta_env();
1549
1613
  var hasBrowserEnv = typeof window !== "undefined" && typeof document !== "undefined";
1550
1614
  var _navigator = typeof navigator === "object" && navigator || void 0;
1551
1615
  var hasStandardBrowserEnv = hasBrowserEnv && (!_navigator || ["ReactNative", "NativeScript", "NS"].indexOf(_navigator.product) < 0);
@@ -1576,6 +1640,7 @@ function toURLEncodedForm(data, options) {
1576
1640
  }
1577
1641
 
1578
1642
  // node_modules/axios/lib/helpers/formDataToJSON.js
1643
+ init_define_import_meta_env();
1579
1644
  var MAX_DEPTH = DEFAULT_FORM_DATA_MAX_DEPTH;
1580
1645
  function throwIfDepthExceeded(index) {
1581
1646
  if (index > MAX_DEPTH) {
@@ -1644,6 +1709,7 @@ function formDataToJSON(formData) {
1644
1709
  var formDataToJSON_default = formDataToJSON;
1645
1710
 
1646
1711
  // node_modules/axios/lib/core/methodList.js
1712
+ init_define_import_meta_env();
1647
1713
  var methodList = Object.freeze([
1648
1714
  "get",
1649
1715
  "delete",
@@ -1790,11 +1856,13 @@ function transformData(fns, response) {
1790
1856
  }
1791
1857
 
1792
1858
  // node_modules/axios/lib/cancel/isCancel.js
1859
+ init_define_import_meta_env();
1793
1860
  function isCancel(value) {
1794
1861
  return !!(value && value.__CANCEL__);
1795
1862
  }
1796
1863
 
1797
1864
  // node_modules/axios/lib/cancel/CanceledError.js
1865
+ init_define_import_meta_env();
1798
1866
  var CanceledError = class extends AxiosError_default {
1799
1867
  /**
1800
1868
  * A `CanceledError` is an object that is thrown when an operation is canceled.
@@ -1813,7 +1881,14 @@ var CanceledError = class extends AxiosError_default {
1813
1881
  };
1814
1882
  var CanceledError_default = CanceledError;
1815
1883
 
1884
+ // node_modules/axios/lib/adapters/adapters.js
1885
+ init_define_import_meta_env();
1886
+
1887
+ // node_modules/axios/lib/adapters/xhr.js
1888
+ init_define_import_meta_env();
1889
+
1816
1890
  // node_modules/axios/lib/core/settle.js
1891
+ init_define_import_meta_env();
1817
1892
  function settle(resolve, reject, response) {
1818
1893
  const validateStatus2 = response.config.validateStatus;
1819
1894
  if (!response.status || !validateStatus2 || validateStatus2(response.status)) {
@@ -1830,6 +1905,7 @@ function settle(resolve, reject, response) {
1830
1905
  }
1831
1906
 
1832
1907
  // node_modules/axios/lib/helpers/normalizeURLForProtocolCheck.js
1908
+ init_define_import_meta_env();
1833
1909
  var urlParserControlCharacters = /[\t\n\r]/g;
1834
1910
  function normalizeURLForProtocolCheck(url) {
1835
1911
  if (typeof url !== "string") {
@@ -1843,12 +1919,17 @@ function normalizeURLForProtocolCheck(url) {
1843
1919
  }
1844
1920
 
1845
1921
  // node_modules/axios/lib/helpers/parseProtocol.js
1922
+ init_define_import_meta_env();
1846
1923
  function parseProtocol(url) {
1847
1924
  const match = /^([-+\w]{1,25}):(?:\/\/)?/.exec(url);
1848
1925
  return match && match[1] || "";
1849
1926
  }
1850
1927
 
1928
+ // node_modules/axios/lib/helpers/progressEventReducer.js
1929
+ init_define_import_meta_env();
1930
+
1851
1931
  // node_modules/axios/lib/helpers/speedometer.js
1932
+ init_define_import_meta_env();
1852
1933
  function speedometer(samplesCount, min) {
1853
1934
  samplesCount = samplesCount || 10;
1854
1935
  const bytes = new Array(samplesCount);
@@ -1885,6 +1966,7 @@ function speedometer(samplesCount, min) {
1885
1966
  var speedometer_default = speedometer;
1886
1967
 
1887
1968
  // node_modules/axios/lib/helpers/throttle.js
1969
+ init_define_import_meta_env();
1888
1970
  function throttle(fn, freq) {
1889
1971
  let timestamp = 0;
1890
1972
  let threshold = 1e3 / freq;
@@ -1961,7 +2043,11 @@ var progressEventDecorator = (total, throttled) => {
1961
2043
  };
1962
2044
  var asyncDecorator = (fn, scheduler = utils_default.asap) => (...args) => scheduler(() => fn(...args));
1963
2045
 
2046
+ // node_modules/axios/lib/helpers/resolveConfig.js
2047
+ init_define_import_meta_env();
2048
+
1964
2049
  // node_modules/axios/lib/helpers/isURLSameOrigin.js
2050
+ init_define_import_meta_env();
1965
2051
  var isURLSameOrigin_default = platform_default.hasStandardBrowserEnv ? /* @__PURE__ */ ((origin2, isMSIE) => (url) => {
1966
2052
  url = new URL(url, platform_default.origin);
1967
2053
  return origin2.protocol === url.protocol && origin2.host === url.host && (isMSIE || origin2.port === url.port);
@@ -1971,6 +2057,7 @@ var isURLSameOrigin_default = platform_default.hasStandardBrowserEnv ? /* @__PUR
1971
2057
  ) : () => true;
1972
2058
 
1973
2059
  // node_modules/axios/lib/helpers/cookies.js
2060
+ init_define_import_meta_env();
1974
2061
  var cookies_default = platform_default.hasStandardBrowserEnv ? (
1975
2062
  // Standard browser envs support document.cookie
1976
2063
  {
@@ -2027,7 +2114,11 @@ var cookies_default = platform_default.hasStandardBrowserEnv ? (
2027
2114
  }
2028
2115
  );
2029
2116
 
2117
+ // node_modules/axios/lib/core/buildFullPath.js
2118
+ init_define_import_meta_env();
2119
+
2030
2120
  // node_modules/axios/lib/helpers/isAbsoluteURL.js
2121
+ init_define_import_meta_env();
2031
2122
  function isAbsoluteURL(url) {
2032
2123
  if (typeof url !== "string") {
2033
2124
  return false;
@@ -2036,6 +2127,7 @@ function isAbsoluteURL(url) {
2036
2127
  }
2037
2128
 
2038
2129
  // node_modules/axios/lib/helpers/combineURLs.js
2130
+ init_define_import_meta_env();
2039
2131
  function combineURLs(baseURL, relativeURL) {
2040
2132
  if (!relativeURL) {
2041
2133
  return baseURL;
@@ -2093,6 +2185,7 @@ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls, config) {
2093
2185
  }
2094
2186
 
2095
2187
  // node_modules/axios/lib/core/mergeConfig.js
2188
+ init_define_import_meta_env();
2096
2189
  var headersToObject = (thing) => thing instanceof AxiosHeaders_default ? { ...thing } : thing;
2097
2190
  var ownEnumerableKeys = (thing) => {
2098
2191
  if (Object.getOwnPropertySymbols && Object.getOwnPropertyDescriptor) {
@@ -2221,6 +2314,7 @@ function mergeConfig(config1, config2) {
2221
2314
  }
2222
2315
 
2223
2316
  // node_modules/axios/lib/core/setFormDataHeaders.js
2317
+ init_define_import_meta_env();
2224
2318
  var FORM_DATA_CONTENT_HEADERS = ["content-type", "content-length"];
2225
2319
  function setFormDataHeaders(headers, formHeaders, policy) {
2226
2320
  if (policy !== "content-only") {
@@ -2463,7 +2557,11 @@ var xhr_default = isXHRAdapterSupported && function(config) {
2463
2557
  });
2464
2558
  };
2465
2559
 
2560
+ // node_modules/axios/lib/adapters/fetch.js
2561
+ init_define_import_meta_env();
2562
+
2466
2563
  // node_modules/axios/lib/helpers/composeSignals.js
2564
+ init_define_import_meta_env();
2467
2565
  var composeSignals = (signals, timeout) => {
2468
2566
  signals = signals ? signals.filter(Boolean) : [];
2469
2567
  if (!timeout && !signals.length) {
@@ -2513,6 +2611,7 @@ var composeSignals = (signals, timeout) => {
2513
2611
  var composeSignals_default = composeSignals;
2514
2612
 
2515
2613
  // node_modules/axios/lib/helpers/trackStream.js
2614
+ init_define_import_meta_env();
2516
2615
  var streamChunk = function* (chunk, chunkSize) {
2517
2616
  let len = chunk.byteLength;
2518
2617
  if (!chunkSize || len < chunkSize) {
@@ -2593,6 +2692,7 @@ var trackStream = (stream, chunkSize, onProgress, onFinish) => {
2593
2692
  };
2594
2693
 
2595
2694
  // node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js
2695
+ init_define_import_meta_env();
2596
2696
  var isHexDigit = (charCode) => charCode >= 48 && charCode <= 57 || charCode >= 65 && charCode <= 70 || charCode >= 97 && charCode <= 102;
2597
2697
  var isPercentEncodedByte = (str, i, len) => i + 2 < len && isHexDigit(str.charCodeAt(i + 1)) && isHexDigit(str.charCodeAt(i + 2));
2598
2698
  var hexValue = (charCode) => charCode <= 57 ? charCode - 48 : (charCode & 223) - 55;
@@ -2693,6 +2793,7 @@ function estimateDataURLDecodedBytes(url) {
2693
2793
  }
2694
2794
 
2695
2795
  // node_modules/axios/lib/env/data.js
2796
+ init_define_import_meta_env();
2696
2797
  var VERSION = "1.20.0";
2697
2798
 
2698
2799
  // node_modules/axios/lib/adapters/fetch.js
@@ -3269,6 +3370,7 @@ function dispatchRequest(_config) {
3269
3370
  }
3270
3371
 
3271
3372
  // node_modules/axios/lib/helpers/validator.js
3373
+ init_define_import_meta_env();
3272
3374
  var validators = {};
3273
3375
  ["object", "boolean", "number", "function", "string", "symbol"].forEach((type, i) => {
3274
3376
  validators[type] = function validator(thing) {
@@ -3554,6 +3656,7 @@ utils_default.forEach(["post", "put", "patch", "query"], function forEachMethodW
3554
3656
  var Axios_default = Axios;
3555
3657
 
3556
3658
  // node_modules/axios/lib/cancel/CancelToken.js
3659
+ init_define_import_meta_env();
3557
3660
  var CancelToken = class _CancelToken {
3558
3661
  constructor(executor) {
3559
3662
  if (typeof executor !== "function") {
@@ -3652,6 +3755,7 @@ var CancelToken = class _CancelToken {
3652
3755
  var CancelToken_default = CancelToken;
3653
3756
 
3654
3757
  // node_modules/axios/lib/helpers/spread.js
3758
+ init_define_import_meta_env();
3655
3759
  function spread(callback) {
3656
3760
  return function wrap(arr) {
3657
3761
  return callback.apply(null, arr);
@@ -3659,11 +3763,13 @@ function spread(callback) {
3659
3763
  }
3660
3764
 
3661
3765
  // node_modules/axios/lib/helpers/isAxiosError.js
3766
+ init_define_import_meta_env();
3662
3767
  function isAxiosError(payload) {
3663
3768
  return utils_default.isObject(payload) && payload.isAxiosError === true;
3664
3769
  }
3665
3770
 
3666
3771
  // node_modules/axios/lib/helpers/HttpStatusCode.js
3772
+ init_define_import_meta_env();
3667
3773
  var HttpStatusCode = {
3668
3774
  Continue: 100,
3669
3775
  SwitchingProtocols: 101,
@@ -3810,6 +3916,7 @@ import { toast } from "sonner";
3810
3916
  import i18n2 from "i18next";
3811
3917
 
3812
3918
  // src/ui/lib/base-path.ts
3919
+ init_define_import_meta_env();
3813
3920
  function getBasePath() {
3814
3921
  const runtime = document.querySelector('meta[name="termix-base-path"]')?.content.trim() || window.__TERMIX_BASE_PATH__;
3815
3922
  if (runtime) {
@@ -3820,7 +3927,14 @@ function getBasePath() {
3820
3927
  return base.endsWith("/") ? base.slice(0, -1) : base;
3821
3928
  }
3822
3929
 
3930
+ // src/ui/shell/TabContext.tsx
3931
+ init_define_import_meta_env();
3932
+
3933
+ // src/ui/shell/tab-registry.ts
3934
+ init_define_import_meta_env();
3935
+
3823
3936
  // src/ui/lib/registry.ts
3937
+ init_define_import_meta_env();
3824
3938
  import { useSyncExternalStore } from "react";
3825
3939
  function createRegistry(sort) {
3826
3940
  const items = /* @__PURE__ */ new Map();
@@ -3871,7 +3985,11 @@ function byOrderThenId(a, b) {
3871
3985
  return (a.order ?? 0) - (b.order ?? 0) || a.id.localeCompare(b.id);
3872
3986
  }
3873
3987
 
3988
+ // src/ui/plugin-host/view-ownership.ts
3989
+ init_define_import_meta_env();
3990
+
3874
3991
  // src/ui/plugin-host/plugin-store.ts
3992
+ init_define_import_meta_env();
3875
3993
  import { useSyncExternalStore as useSyncExternalStore2 } from "react";
3876
3994
  var state = { loaded: false, settled: false, records: /* @__PURE__ */ new Map() };
3877
3995
  var listeners = /* @__PURE__ */ new Set();
@@ -3931,6 +4049,9 @@ function getPluginRecord(pluginId) {
3931
4049
  function knownPluginIds() {
3932
4050
  return [...state.records.keys()];
3933
4051
  }
4052
+ function resetPluginStore() {
4053
+ commit({ loaded: false, settled: false, records: /* @__PURE__ */ new Map() });
4054
+ }
3934
4055
 
3935
4056
  // src/ui/plugin-host/view-ownership.ts
3936
4057
  function declares(record, kind, id) {
@@ -3940,6 +4061,9 @@ function declares(record, kind, id) {
3940
4061
  if (kind === "panel") {
3941
4062
  return !!contributes.panels?.some((panel) => panel.id === id) || !!contributes.tabs?.some((tab) => tab.id === id);
3942
4063
  }
4064
+ if (kind === "layout") {
4065
+ return !!contributes.layouts?.some((layout) => layout.id === id);
4066
+ }
3943
4067
  return !!contributes.dashboardCards?.some((card) => card.id === id);
3944
4068
  }
3945
4069
  function viewOwner(kind, id) {
@@ -3979,6 +4103,29 @@ var getTabType = registry.get;
3979
4103
  var listTabTypes = registry.list;
3980
4104
  var useTabTypes = registry.useList;
3981
4105
  var resetTabTypes = registry.reset;
4106
+ var CORE_PERSISTENT = /* @__PURE__ */ new Set();
4107
+ var CORE_SESSION = /* @__PURE__ */ new Set();
4108
+ var CORE_HOSTLESS = /* @__PURE__ */ new Set(["dashboard"]);
4109
+ function isOwnedButAbsent(type) {
4110
+ return !registry.get(type) && !!viewOwner("tab", type);
4111
+ }
4112
+ function isPersistentTabType(type) {
4113
+ if (CORE_PERSISTENT.has(type)) return true;
4114
+ const def = registry.get(type);
4115
+ if (def) return !!def.persistent;
4116
+ return isOwnedButAbsent(type);
4117
+ }
4118
+ function isSessionTabType(type) {
4119
+ return CORE_SESSION.has(type) || !!registry.get(type)?.session;
4120
+ }
4121
+ function isHostlessTabType(type) {
4122
+ return CORE_HOSTLESS.has(type) || !!registry.get(type)?.hostless;
4123
+ }
4124
+ function canRestoreTabType(type, host) {
4125
+ const def = registry.get(type);
4126
+ if (!host) return isHostlessTabType(type) || isOwnedButAbsent(type);
4127
+ return def?.restore ? def.restore(host) : true;
4128
+ }
3982
4129
  function tabTypeForActivity(activityType) {
3983
4130
  return registry.list().find(
3984
4131
  (def) => def.id === activityType || def.activityTypes?.includes(activityType)
@@ -4268,6 +4415,7 @@ function TabProvider({ children }) {
4268
4415
  }
4269
4416
 
4270
4417
  // src/ui/lib/frontend-logger.ts
4418
+ init_define_import_meta_env();
4271
4419
  var FrontendLogger = class {
4272
4420
  serviceName;
4273
4421
  serviceIcon;
@@ -4535,6 +4683,7 @@ function createFrontendLogger(serviceName, serviceIcon = "\u{1F9E9}", serviceCol
4535
4683
  }
4536
4684
 
4537
4685
  // src/ui/lib/db-health-monitor.ts
4686
+ init_define_import_meta_env();
4538
4687
  var DatabaseHealthMonitor = class _DatabaseHealthMonitor {
4539
4688
  static instance;
4540
4689
  listeners = /* @__PURE__ */ new Map();
@@ -4608,6 +4757,7 @@ var DatabaseHealthMonitor = class _DatabaseHealthMonitor {
4608
4757
  var dbHealthMonitor = DatabaseHealthMonitor.getInstance();
4609
4758
 
4610
4759
  // src/ui/lib/device-id.ts
4760
+ init_define_import_meta_env();
4611
4761
  var DEVICE_ID_STORAGE_KEY = "termixDeviceId";
4612
4762
  var DEVICE_ID_PATTERN = /^[a-f0-9]{64}$/;
4613
4763
  function createDeviceId() {
@@ -4629,10 +4779,18 @@ function getDeviceId() {
4629
4779
  }
4630
4780
  }
4631
4781
 
4782
+ // src/ui/api/ssh-host-management-api.ts
4783
+ init_define_import_meta_env();
4784
+
4785
+ // src/ui/lib/hosts-request-cache.ts
4786
+ init_define_import_meta_env();
4787
+
4632
4788
  // src/ui/lib/sync-events.ts
4789
+ init_define_import_meta_env();
4633
4790
  var SYNC_CHANGED_EVENT = "termix:sync-changed";
4634
4791
 
4635
4792
  // src/ui/lib/ttl-request-cache.ts
4793
+ init_define_import_meta_env();
4636
4794
  function createTtlRequestCache(ttlMs) {
4637
4795
  let cached2 = null;
4638
4796
  let inflight2 = null;
@@ -4691,6 +4849,18 @@ function getCachedSSHHosts(loader) {
4691
4849
  bindInvalidationListeners();
4692
4850
  return hostsCache.get(loader);
4693
4851
  }
4852
+ function getCachedServerStatuses(loader) {
4853
+ return statusCache.get(loader);
4854
+ }
4855
+ function invalidateServerStatusCache() {
4856
+ statusCache.invalidate();
4857
+ }
4858
+ function getCachedSSHFolders(loader) {
4859
+ return foldersCache.get(loader);
4860
+ }
4861
+ function invalidateSSHFoldersCache() {
4862
+ foldersCache.invalidate();
4863
+ }
4694
4864
  function invalidateHostsAndStatusCaches() {
4695
4865
  hostsCache.invalidate();
4696
4866
  statusCache.invalidate();
@@ -4710,8 +4880,85 @@ async function getSSHHosts() {
4710
4880
  throw handleApiError(error, "fetch SSH hosts");
4711
4881
  }
4712
4882
  }
4883
+ async function createSSHHost(hostData) {
4884
+ try {
4885
+ if (hostData.authType === "key" && hostData.key instanceof File) {
4886
+ const formData = new FormData();
4887
+ formData.append("key", hostData.key);
4888
+ const dataWithoutFile = { ...hostData, key: void 0 };
4889
+ formData.append("data", JSON.stringify(dataWithoutFile));
4890
+ const response2 = await sshHostApi.post("/db/host", formData, {
4891
+ headers: { "Content-Type": "multipart/form-data" }
4892
+ });
4893
+ invalidateHostsAndStatusCaches();
4894
+ return response2.data;
4895
+ }
4896
+ const response = await sshHostApi.post("/db/host", hostData);
4897
+ invalidateHostsAndStatusCaches();
4898
+ return response.data;
4899
+ } catch (error) {
4900
+ throw handleApiError(error, "create SSH host");
4901
+ }
4902
+ }
4903
+ async function updateSSHHost(hostId, hostData) {
4904
+ try {
4905
+ if (hostData.authType === "key" && hostData.key instanceof File) {
4906
+ const formData = new FormData();
4907
+ formData.append("key", hostData.key);
4908
+ const dataWithoutFile = { ...hostData, key: void 0 };
4909
+ formData.append("data", JSON.stringify(dataWithoutFile));
4910
+ const response2 = await sshHostApi.put(`/db/host/${hostId}`, formData, {
4911
+ headers: { "Content-Type": "multipart/form-data" }
4912
+ });
4913
+ invalidateHostsAndStatusCaches();
4914
+ return response2.data;
4915
+ }
4916
+ const response = await sshHostApi.put(`/db/host/${hostId}`, hostData);
4917
+ invalidateHostsAndStatusCaches();
4918
+ return response.data;
4919
+ } catch (error) {
4920
+ throw handleApiError(error, "update SSH host");
4921
+ }
4922
+ }
4923
+ async function bulkUpdateSSHHosts(hostIds, updates) {
4924
+ try {
4925
+ const response = await sshHostApi.patch("/bulk-update", {
4926
+ hostIds,
4927
+ updates
4928
+ });
4929
+ invalidateHostsAndStatusCaches();
4930
+ return response.data;
4931
+ } catch (error) {
4932
+ handleApiError(error, "bulk update SSH hosts");
4933
+ }
4934
+ }
4935
+ async function reorderSSHHosts(positions) {
4936
+ try {
4937
+ const response = await sshHostApi.put("/reorder", { positions });
4938
+ invalidateHostsAndStatusCaches();
4939
+ return response.data;
4940
+ } catch (error) {
4941
+ handleApiError(error, "reorder SSH hosts");
4942
+ }
4943
+ }
4944
+ async function deleteSSHHost(hostId) {
4945
+ try {
4946
+ const response = await sshHostApi.delete(`/db/host/${hostId}`);
4947
+ invalidateHostsAndStatusCaches();
4948
+ return response.data;
4949
+ } catch (error) {
4950
+ handleApiError(error, "delete SSH host");
4951
+ }
4952
+ }
4953
+
4954
+ // src/ui/api/host-status-api.ts
4955
+ init_define_import_meta_env();
4956
+
4957
+ // src/ui/lib/connection-origin.ts
4958
+ init_define_import_meta_env();
4713
4959
 
4714
4960
  // src/ui/lib/ws-auth.ts
4961
+ init_define_import_meta_env();
4715
4962
  var JWT_PROTOCOL_PREFIX = "termix.jwt.";
4716
4963
  function websocketAuthProtocols(token) {
4717
4964
  return token ? [`${JWT_PROTOCOL_PREFIX}${token}`] : [];
@@ -4765,7 +5012,416 @@ async function buildOriginWsUrl({
4765
5012
  };
4766
5013
  }
4767
5014
 
5015
+ // src/ui/api/host-status-api.ts
5016
+ var STATUS_RETRY_SCHEDULE = [
5017
+ { timeoutMs: 2e3, pauseAfterMs: 3e3 },
5018
+ { timeoutMs: 5e3, pauseAfterMs: 5e3 },
5019
+ { timeoutMs: 8e3, pauseAfterMs: null }
5020
+ ];
5021
+ function isTransientStatusError(error) {
5022
+ if (!axios_default.isAxiosError(error)) return false;
5023
+ if (error.response) {
5024
+ return false;
5025
+ }
5026
+ const code = error.code;
5027
+ if (!code) {
5028
+ return true;
5029
+ }
5030
+ return code === "ECONNABORTED" || code === "ETIMEDOUT" || code === "ERR_NETWORK" || code === "ECONNREFUSED" || code === "ECONNRESET";
5031
+ }
5032
+ async function getAllServerStatuses() {
5033
+ return getCachedServerStatuses(async () => {
5034
+ let lastError = null;
5035
+ let localStatuses = {};
5036
+ let localHostIds = null;
5037
+ let remoteHostsBySyncId = null;
5038
+ if (isElectron()) {
5039
+ const response = await sshHostApi.get("/db/host");
5040
+ const defaultOrigin = await resolveConnectionOrigin({
5041
+ connectionOrigin: null
5042
+ });
5043
+ const hosts = response.data || [];
5044
+ localHostIds = hosts.filter((host) => (host.connectionOrigin ?? defaultOrigin) === "local").map((host) => host.id);
5045
+ remoteHostsBySyncId = new Map(
5046
+ hosts.filter(
5047
+ (host) => (host.connectionOrigin ?? defaultOrigin) === "remote" && !!host.syncId
5048
+ ).map((host) => [host.syncId, host.id])
5049
+ );
5050
+ }
5051
+ for (let i = 0; i < STATUS_RETRY_SCHEDULE.length; i++) {
5052
+ const { timeoutMs, pauseAfterMs } = STATUS_RETRY_SCHEDULE[i];
5053
+ const isFinalAttempt = i === STATUS_RETRY_SCHEDULE.length - 1;
5054
+ try {
5055
+ const response = await sshHostApi.get("/status", {
5056
+ timeout: timeoutMs,
5057
+ ...localHostIds === null ? {} : { params: { hostIds: localHostIds.join(",") } },
5058
+ // Silence per-attempt interceptor logging & health-monitor side
5059
+ // effects on all attempts except the final one, so background
5060
+ // blips don't look like real outages.
5061
+ __silentRetry: !isFinalAttempt
5062
+ });
5063
+ localStatuses = response.data || {};
5064
+ lastError = null;
5065
+ break;
5066
+ } catch (error) {
5067
+ lastError = error;
5068
+ if (!isTransientStatusError(error)) {
5069
+ break;
5070
+ }
5071
+ if (pauseAfterMs === null) {
5072
+ break;
5073
+ }
5074
+ await new Promise((resolve) => setTimeout(resolve, pauseAfterMs));
5075
+ }
5076
+ }
5077
+ if (lastError) handleApiError(lastError, "fetch server statuses");
5078
+ if (remoteHostsBySyncId?.size && await getLinkedSession()) {
5079
+ try {
5080
+ const remoteResult = await getRemoteCoreApi().get(
5081
+ "/sync/v2/host-status",
5082
+ {
5083
+ timeout: 8e3,
5084
+ __silentRetry: true
5085
+ }
5086
+ );
5087
+ const merged = { ...localStatuses };
5088
+ for (const [syncId, status] of Object.entries(
5089
+ remoteResult.data || {}
5090
+ )) {
5091
+ const localId = remoteHostsBySyncId.get(syncId);
5092
+ if (localId !== void 0) merged[localId] = status;
5093
+ }
5094
+ return merged;
5095
+ } catch {
5096
+ }
5097
+ }
5098
+ return localStatuses;
5099
+ });
5100
+ }
5101
+ async function getStatusCheckSettings() {
5102
+ try {
5103
+ const response = await sshHostApi.get("/status/settings");
5104
+ return response.data;
5105
+ } catch (error) {
5106
+ handleApiError(error, "fetch status check settings");
5107
+ }
5108
+ }
5109
+ async function updateStatusCheckSettings(settings) {
5110
+ try {
5111
+ await sshHostApi.put("/status/settings", settings);
5112
+ } catch (error) {
5113
+ handleApiError(error, "update status check settings");
5114
+ }
5115
+ }
5116
+
5117
+ // src/ui/api/host-sidebar-preferences-api.ts
5118
+ init_define_import_meta_env();
5119
+
5120
+ // src/types/host-sidebar-preferences.ts
5121
+ init_define_import_meta_env();
5122
+ var HOST_SIDEBAR_PREFS_VERSION = 1;
5123
+ var HOST_ROW_FIELD_KEYS = [
5124
+ "showAddress",
5125
+ "showUsername",
5126
+ "showPort",
5127
+ "showPinIcon",
5128
+ "showSharedBadge",
5129
+ "showBadges"
5130
+ ];
5131
+ function defaultHostRowFields() {
5132
+ return {
5133
+ showAddress: true,
5134
+ showUsername: true,
5135
+ showPort: false,
5136
+ showPinIcon: true,
5137
+ showSharedBadge: true,
5138
+ showBadges: true
5139
+ };
5140
+ }
5141
+ var GROUP_KEYS = [
5142
+ "folder",
5143
+ "tag",
5144
+ "status",
5145
+ "protocol",
5146
+ "auth"
5147
+ ];
5148
+ var SORT_KEYS = [
5149
+ "default",
5150
+ "name-asc",
5151
+ "name-desc",
5152
+ "ip-asc",
5153
+ "ip-desc",
5154
+ "status-online",
5155
+ "status-offline",
5156
+ "manual"
5157
+ ];
5158
+ var DENSITIES = ["comfortable", "compact"];
5159
+ var TRAY_TRIGGERS = [
5160
+ "always",
5161
+ "hover",
5162
+ "click",
5163
+ "actionsOnly"
5164
+ ];
5165
+ var HOST_CLICK_BEHAVIORS = [
5166
+ "newTab",
5167
+ "focusExisting",
5168
+ "focusExistingDoubleClickNew"
5169
+ ];
5170
+ var STATUS_COLOR_SCHEMES = ["accent", "status"];
5171
+ var FILTER_STATUS = [
5172
+ "online",
5173
+ "offline",
5174
+ "pinned"
5175
+ ];
5176
+ var AUTH_TYPE_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
5177
+ function defaultHostSidebarPreferences() {
5178
+ return {
5179
+ version: HOST_SIDEBAR_PREFS_VERSION,
5180
+ sort: { key: "default", pinnedFirst: false },
5181
+ groupKey: "folder",
5182
+ filters: {
5183
+ status: [],
5184
+ authType: [],
5185
+ protocol: [],
5186
+ features: [],
5187
+ tags: []
5188
+ },
5189
+ openFolders: [],
5190
+ display: {
5191
+ density: "comfortable",
5192
+ showTags: true,
5193
+ trayTrigger: "always",
5194
+ statusColorScheme: "accent",
5195
+ openOnDoubleClick: false,
5196
+ showFolderPaths: true,
5197
+ hostClickBehavior: "newTab",
5198
+ closeOnOpen: false,
5199
+ barActions: {},
5200
+ ...defaultHostRowFields()
5201
+ }
5202
+ };
5203
+ }
5204
+ var ACTION_ID_PATTERN = /^[a-z0-9][a-z0-9._:-]{0,79}$/;
5205
+ function sanitizeBarActions(input) {
5206
+ if (!input || typeof input !== "object" || Array.isArray(input)) return {};
5207
+ const out = {};
5208
+ for (const [id, value] of Object.entries(input)) {
5209
+ if (ACTION_ID_PATTERN.test(id) && typeof value === "boolean") {
5210
+ out[id] = value;
5211
+ }
5212
+ }
5213
+ return out;
5214
+ }
5215
+ function sanitizeStringArray(input) {
5216
+ if (!Array.isArray(input)) return [];
5217
+ return input.filter((v) => typeof v === "string");
5218
+ }
5219
+ function sanitizeEnumArray(input, allowed) {
5220
+ if (!Array.isArray(input)) return [];
5221
+ return input.filter((v) => allowed.includes(v));
5222
+ }
5223
+ function sanitizeHostSidebarPreferences(input) {
5224
+ const defaults2 = defaultHostSidebarPreferences();
5225
+ if (!input || typeof input !== "object") return defaults2;
5226
+ const obj = input;
5227
+ const sortObj = obj.sort ?? {};
5228
+ const sort = {
5229
+ key: SORT_KEYS.includes(sortObj.key) ? sortObj.key : defaults2.sort.key,
5230
+ pinnedFirst: typeof sortObj.pinnedFirst === "boolean" ? sortObj.pinnedFirst : defaults2.sort.pinnedFirst
5231
+ };
5232
+ const groupKey = GROUP_KEYS.includes(obj.groupKey) ? obj.groupKey : defaults2.groupKey;
5233
+ const filtersObj = obj.filters ?? {};
5234
+ const filters = {
5235
+ status: sanitizeEnumArray(filtersObj.status, FILTER_STATUS),
5236
+ authType: sanitizeStringArray(filtersObj.authType).filter(
5237
+ (value) => AUTH_TYPE_PATTERN.test(value)
5238
+ ),
5239
+ protocol: sanitizeStringArray(filtersObj.protocol).filter(
5240
+ (value) => AUTH_TYPE_PATTERN.test(value)
5241
+ ),
5242
+ features: sanitizeStringArray(filtersObj.features).filter(
5243
+ (value) => AUTH_TYPE_PATTERN.test(value)
5244
+ ),
5245
+ tags: sanitizeStringArray(filtersObj.tags)
5246
+ };
5247
+ const openFolders = sanitizeStringArray(obj.openFolders);
5248
+ const displayObj = obj.display ?? {};
5249
+ const rowFields = {};
5250
+ for (const key of HOST_ROW_FIELD_KEYS) {
5251
+ rowFields[key] = typeof displayObj[key] === "boolean" ? displayObj[key] : defaults2.display[key];
5252
+ }
5253
+ const display = {
5254
+ ...rowFields,
5255
+ density: DENSITIES.includes(displayObj.density) ? displayObj.density : defaults2.display.density,
5256
+ showTags: typeof displayObj.showTags === "boolean" ? displayObj.showTags : defaults2.display.showTags,
5257
+ trayTrigger: TRAY_TRIGGERS.includes(
5258
+ displayObj.trayTrigger
5259
+ ) ? displayObj.trayTrigger : defaults2.display.trayTrigger,
5260
+ statusColorScheme: STATUS_COLOR_SCHEMES.includes(
5261
+ displayObj.statusColorScheme
5262
+ ) ? displayObj.statusColorScheme : defaults2.display.statusColorScheme,
5263
+ openOnDoubleClick: typeof displayObj.openOnDoubleClick === "boolean" ? displayObj.openOnDoubleClick : defaults2.display.openOnDoubleClick,
5264
+ showFolderPaths: typeof displayObj.showFolderPaths === "boolean" ? displayObj.showFolderPaths : defaults2.display.showFolderPaths,
5265
+ hostClickBehavior: HOST_CLICK_BEHAVIORS.includes(
5266
+ displayObj.hostClickBehavior
5267
+ ) ? displayObj.hostClickBehavior : defaults2.display.hostClickBehavior,
5268
+ closeOnOpen: typeof displayObj.closeOnOpen === "boolean" ? displayObj.closeOnOpen : defaults2.display.closeOnOpen,
5269
+ barActions: sanitizeBarActions(displayObj.barActions)
5270
+ };
5271
+ return {
5272
+ version: HOST_SIDEBAR_PREFS_VERSION,
5273
+ sort,
5274
+ groupKey,
5275
+ filters,
5276
+ openFolders,
5277
+ display
5278
+ };
5279
+ }
5280
+
5281
+ // src/ui/api/host-sidebar-preferences-api.ts
5282
+ async function getHostSidebarPreferences() {
5283
+ try {
5284
+ const response = await authApi.get("/host-sidebar/preferences");
5285
+ return sanitizeHostSidebarPreferences(response.data?.preferences);
5286
+ } catch (error) {
5287
+ handleApiError(error, "fetch host sidebar preferences");
5288
+ throw error;
5289
+ }
5290
+ }
5291
+ async function saveHostSidebarPreferences(preferences) {
5292
+ try {
5293
+ await authApi.put("/host-sidebar/preferences", preferences);
5294
+ } catch (error) {
5295
+ handleApiError(error, "save host sidebar preferences");
5296
+ throw error;
5297
+ }
5298
+ }
5299
+
5300
+ // src/ui/api/credential-sidebar-preferences-api.ts
5301
+ init_define_import_meta_env();
5302
+
5303
+ // src/types/credential-sidebar-preferences.ts
5304
+ init_define_import_meta_env();
5305
+ var CREDENTIAL_SIDEBAR_PREFS_VERSION = 1;
5306
+ var CREDENTIAL_ROW_FIELD_KEYS = [
5307
+ "showUsername",
5308
+ "showUsageCount",
5309
+ "showTypeBadge",
5310
+ "showPinIcon",
5311
+ "showSharedBadge"
5312
+ ];
5313
+ function defaultCredentialRowFields() {
5314
+ return {
5315
+ showUsername: true,
5316
+ showUsageCount: true,
5317
+ showTypeBadge: true,
5318
+ showPinIcon: true,
5319
+ showSharedBadge: true
5320
+ };
5321
+ }
5322
+ var SORT_KEYS2 = [
5323
+ "default",
5324
+ "name-asc",
5325
+ "name-desc",
5326
+ "username-asc",
5327
+ "username-desc",
5328
+ "manual"
5329
+ ];
5330
+ var DENSITIES2 = ["comfortable", "compact"];
5331
+ var TRAY_TRIGGERS2 = [
5332
+ "always",
5333
+ "hover",
5334
+ "click",
5335
+ "actionsOnly"
5336
+ ];
5337
+ var TYPE_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
5338
+ function defaultCredentialSidebarPreferences() {
5339
+ return {
5340
+ version: CREDENTIAL_SIDEBAR_PREFS_VERSION,
5341
+ sort: { key: "default", pinnedFirst: false },
5342
+ filters: {
5343
+ type: [],
5344
+ tags: []
5345
+ },
5346
+ openFolders: [],
5347
+ display: {
5348
+ density: "comfortable",
5349
+ showTags: true,
5350
+ trayTrigger: "always",
5351
+ ...defaultCredentialRowFields()
5352
+ }
5353
+ };
5354
+ }
5355
+ function sanitizeStringArray2(input) {
5356
+ if (!Array.isArray(input)) return [];
5357
+ return input.filter((v) => typeof v === "string");
5358
+ }
5359
+ function sanitizeCredentialSidebarPreferences(input) {
5360
+ const defaults2 = defaultCredentialSidebarPreferences();
5361
+ if (!input || typeof input !== "object") return defaults2;
5362
+ const obj = input;
5363
+ const sortObj = obj.sort ?? {};
5364
+ const sort = {
5365
+ key: SORT_KEYS2.includes(sortObj.key) ? sortObj.key : defaults2.sort.key,
5366
+ pinnedFirst: typeof sortObj.pinnedFirst === "boolean" ? sortObj.pinnedFirst : defaults2.sort.pinnedFirst
5367
+ };
5368
+ const filtersObj = obj.filters ?? {};
5369
+ const filters = {
5370
+ type: sanitizeStringArray2(filtersObj.type).filter(
5371
+ (value) => TYPE_PATTERN.test(value)
5372
+ ),
5373
+ tags: sanitizeStringArray2(filtersObj.tags)
5374
+ };
5375
+ const openFolders = sanitizeStringArray2(obj.openFolders);
5376
+ const displayObj = obj.display ?? {};
5377
+ const rowFields = {};
5378
+ for (const key of CREDENTIAL_ROW_FIELD_KEYS) {
5379
+ rowFields[key] = typeof displayObj[key] === "boolean" ? displayObj[key] : defaults2.display[key];
5380
+ }
5381
+ const display = {
5382
+ ...rowFields,
5383
+ density: DENSITIES2.includes(displayObj.density) ? displayObj.density : defaults2.display.density,
5384
+ showTags: typeof displayObj.showTags === "boolean" ? displayObj.showTags : defaults2.display.showTags,
5385
+ trayTrigger: TRAY_TRIGGERS2.includes(
5386
+ displayObj.trayTrigger
5387
+ ) ? displayObj.trayTrigger : defaults2.display.trayTrigger
5388
+ };
5389
+ return {
5390
+ version: CREDENTIAL_SIDEBAR_PREFS_VERSION,
5391
+ sort,
5392
+ filters,
5393
+ openFolders,
5394
+ display
5395
+ };
5396
+ }
5397
+
5398
+ // src/ui/api/credential-sidebar-preferences-api.ts
5399
+ async function getCredentialSidebarPreferences() {
5400
+ try {
5401
+ const response = await authApi.get("/credential-sidebar/preferences");
5402
+ return sanitizeCredentialSidebarPreferences(response.data?.preferences);
5403
+ } catch (error) {
5404
+ handleApiError(error, "fetch credential sidebar preferences");
5405
+ throw error;
5406
+ }
5407
+ }
5408
+ async function saveCredentialSidebarPreferences(preferences) {
5409
+ try {
5410
+ await authApi.put("/credential-sidebar/preferences", preferences);
5411
+ } catch (error) {
5412
+ handleApiError(error, "save credential sidebar preferences");
5413
+ throw error;
5414
+ }
5415
+ }
5416
+
5417
+ // src/ui/api/ui-preferences-api.ts
5418
+ init_define_import_meta_env();
5419
+
5420
+ // src/types/ui-preferences.ts
5421
+ init_define_import_meta_env();
5422
+
4768
5423
  // src/types/onboarding.ts
5424
+ init_define_import_meta_env();
4769
5425
  var LEGACY_SEEN = Object.freeze({
4770
5426
  plugins: 1,
4771
5427
  "desktop-sync": 1,
@@ -4900,7 +5556,52 @@ var AREA_SPECS = {
4900
5556
  };
4901
5557
  var UI_AREA_KEYS = Object.keys(AREA_SPECS);
4902
5558
 
5559
+ // src/ui/api/settings-api.ts
5560
+ init_define_import_meta_env();
5561
+ async function getLogLevel() {
5562
+ try {
5563
+ const response = await authApi.get("/users/log-level");
5564
+ return response.data;
5565
+ } catch (error) {
5566
+ handleApiError(error, "fetch log level");
5567
+ }
5568
+ }
5569
+ async function updateLogLevel(level) {
5570
+ try {
5571
+ await authApi.patch("/users/log-level", { level });
5572
+ } catch (error) {
5573
+ handleApiError(error, "update log level");
5574
+ }
5575
+ }
5576
+ async function getSessionTimeout() {
5577
+ try {
5578
+ const response = await authApi.get("/users/session-timeout");
5579
+ return response.data;
5580
+ } catch (error) {
5581
+ handleApiError(error, "fetch session timeout");
5582
+ }
5583
+ }
5584
+ async function updateSessionTimeout(timeoutHours) {
5585
+ try {
5586
+ await authApi.patch("/users/session-timeout", { timeoutHours });
5587
+ } catch (error) {
5588
+ handleApiError(error, "update session timeout");
5589
+ }
5590
+ }
5591
+ async function getBranding() {
5592
+ try {
5593
+ const response = await authApi.get("/users/branding");
5594
+ return response.data;
5595
+ } catch (error) {
5596
+ handleApiError(error, "fetch branding settings");
5597
+ }
5598
+ }
5599
+
5600
+ // src/ui/api/user-management-api.ts
5601
+ init_define_import_meta_env();
5602
+
4903
5603
  // src/ui/lib/remote-server-api.ts
5604
+ init_define_import_meta_env();
4904
5605
  async function hydrateLocalSharedHostAuth(host) {
4905
5606
  return host;
4906
5607
  }
@@ -4922,26 +5623,362 @@ async function resolveRemoteHostId(syncId) {
4922
5623
  }
4923
5624
 
4924
5625
  // src/ui/api/user-management-api.ts
4925
- async function getPasswordResetAllowed() {
5626
+ async function getUserList(options = {}) {
4926
5627
  try {
4927
- const response = await authApi.get("/users/password-reset-allowed");
4928
- return response.data.allowed;
5628
+ const api = await getConnectedRemoteApi() ?? authApi;
5629
+ const response = await api.get("/users/list", {
5630
+ params: {
5631
+ ...options.search ? { search: options.search } : {},
5632
+ ...options.limit ? { limit: options.limit } : {},
5633
+ ...options.offset ? { offset: options.offset } : {}
5634
+ }
5635
+ });
5636
+ return response.data;
4929
5637
  } catch (error) {
4930
- handleApiError(error, "get password reset allowed");
5638
+ handleApiError(error, "fetch user list");
4931
5639
  }
4932
5640
  }
4933
-
4934
- // src/ui/api/system-status-api.ts
4935
- async function getVersionInfo(checkRemote = true) {
5641
+ async function getSessions() {
4936
5642
  try {
4937
- const response = await authApi.get(
4938
- `/version${checkRemote ? "" : "?checkRemote=false"}`
5643
+ const response = await authApi.get("/users/sessions");
5644
+ return response.data;
5645
+ } catch (error) {
5646
+ handleApiError(error, "fetch sessions");
5647
+ }
5648
+ }
5649
+ async function revokeSession(sessionId) {
5650
+ try {
5651
+ const response = await authApi.delete(`/users/sessions/${sessionId}`);
5652
+ return response.data;
5653
+ } catch (error) {
5654
+ handleApiError(error, "revoke session");
5655
+ }
5656
+ }
5657
+ async function revokeAllUserSessions(userId) {
5658
+ try {
5659
+ const response = await authApi.post("/users/sessions/revoke-all", {
5660
+ targetUserId: userId,
5661
+ exceptCurrent: false
5662
+ });
5663
+ return response.data;
5664
+ } catch (error) {
5665
+ handleApiError(error, "revoke all user sessions");
5666
+ }
5667
+ }
5668
+ async function createApiKey(name, userId, expiresAt) {
5669
+ try {
5670
+ const response = await authApi.post("/users/api-keys", {
5671
+ name,
5672
+ userId,
5673
+ expiresAt: expiresAt ?? null
5674
+ });
5675
+ return response.data;
5676
+ } catch (error) {
5677
+ handleApiError(error, "create API key");
5678
+ }
5679
+ }
5680
+ async function getApiKeys() {
5681
+ try {
5682
+ const response = await authApi.get("/users/api-keys");
5683
+ return response.data;
5684
+ } catch (error) {
5685
+ handleApiError(error, "fetch API keys");
5686
+ }
5687
+ }
5688
+ async function deleteApiKey(keyId) {
5689
+ try {
5690
+ const response = await authApi.delete(`/users/api-keys/${keyId}`);
5691
+ return response.data;
5692
+ } catch (error) {
5693
+ handleApiError(error, "delete API key");
5694
+ }
5695
+ }
5696
+ async function makeUserAdmin(userId) {
5697
+ try {
5698
+ const response = await authApi.post("/users/make-admin", { userId });
5699
+ return response.data;
5700
+ } catch (error) {
5701
+ handleApiError(error, "make user admin");
5702
+ }
5703
+ }
5704
+ async function removeAdminStatus(userId) {
5705
+ try {
5706
+ const response = await authApi.post("/users/remove-admin", { userId });
5707
+ return response.data;
5708
+ } catch (error) {
5709
+ handleApiError(error, "remove admin status");
5710
+ }
5711
+ }
5712
+ async function deleteUser(username, successorUserId) {
5713
+ try {
5714
+ const response = await authApi.delete("/users/delete-user", {
5715
+ data: { username, successorUserId }
5716
+ });
5717
+ return response.data;
5718
+ } catch (error) {
5719
+ handleApiError(error, "delete user");
5720
+ }
5721
+ }
5722
+ async function deleteAccount(password) {
5723
+ try {
5724
+ const response = await authApi.delete("/users/delete-account", {
5725
+ data: { password }
5726
+ });
5727
+ return response.data;
5728
+ } catch (error) {
5729
+ handleApiError(error, "delete account");
5730
+ }
5731
+ }
5732
+ async function adminResetUserPassword(userId, newPassword, confirmDataWipe = false) {
5733
+ const response = await authApi.post("/users/admin/reset-password", {
5734
+ userId,
5735
+ newPassword,
5736
+ confirmDataWipe
5737
+ });
5738
+ return response.data;
5739
+ }
5740
+ async function adminExportUserData(userId) {
5741
+ try {
5742
+ const response = await authApi.get(
5743
+ `/users/admin/export/${encodeURIComponent(userId)}`,
5744
+ { timeout: 12e4 }
5745
+ );
5746
+ return response.data;
5747
+ } catch (error) {
5748
+ handleApiError(error, "export user data");
5749
+ }
5750
+ }
5751
+ async function updateRegistrationAllowed(allowed) {
5752
+ try {
5753
+ const response = await authApi.patch("/users/registration-allowed", {
5754
+ allowed
5755
+ });
5756
+ return response.data;
5757
+ } catch (error) {
5758
+ handleApiError(error, "update registration allowed");
5759
+ }
5760
+ }
5761
+ async function getExternalAutoProvision() {
5762
+ try {
5763
+ const response = await authApi.get("/users/external-auto-provision");
5764
+ return response.data;
5765
+ } catch (error) {
5766
+ handleApiError(error, "check OIDC auto-provision status");
5767
+ }
5768
+ }
5769
+ async function updateExternalAutoProvision(enabled) {
5770
+ try {
5771
+ const response = await authApi.patch("/users/external-auto-provision", {
5772
+ enabled
5773
+ });
5774
+ return response.data;
5775
+ } catch (error) {
5776
+ handleApiError(error, "update OIDC auto-provision");
5777
+ }
5778
+ }
5779
+ async function getSecondFactorAfterExternalLogin() {
5780
+ try {
5781
+ const response = await authApi.get(
5782
+ "/users/second-factor-after-external-login"
5783
+ );
5784
+ return response.data;
5785
+ } catch (error) {
5786
+ handleApiError(error, "check second factor after external login status");
5787
+ }
5788
+ }
5789
+ async function updateSecondFactorAfterExternalLogin(enabled) {
5790
+ try {
5791
+ const response = await authApi.patch(
5792
+ "/users/second-factor-after-external-login",
5793
+ { enabled }
5794
+ );
5795
+ return response.data;
5796
+ } catch (error) {
5797
+ handleApiError(error, "update second factor after external login");
5798
+ }
5799
+ }
5800
+ async function updatePasswordLoginAllowed(allowed) {
5801
+ try {
5802
+ const response = await authApi.patch("/users/password-login-allowed", {
5803
+ allowed
5804
+ });
5805
+ return response.data;
5806
+ } catch (error) {
5807
+ handleApiError(error, "update password login allowed");
5808
+ }
5809
+ }
5810
+ async function getPasswordResetAllowed() {
5811
+ try {
5812
+ const response = await authApi.get("/users/password-reset-allowed");
5813
+ return response.data.allowed;
5814
+ } catch (error) {
5815
+ handleApiError(error, "get password reset allowed");
5816
+ }
5817
+ }
5818
+ async function updatePasswordResetAllowed(allowed) {
5819
+ try {
5820
+ const response = await authApi.patch("/users/password-reset-allowed", {
5821
+ allowed
5822
+ });
5823
+ return response.data;
5824
+ } catch (error) {
5825
+ handleApiError(error, "update password reset allowed");
5826
+ }
5827
+ }
5828
+
5829
+ // src/ui/api/admin-user-data-api.ts
5830
+ init_define_import_meta_env();
5831
+ var ADMIN_TARGET_USER_HEADER = "X-Admin-Target-User";
5832
+ function adminHeaders(targetUserId) {
5833
+ return { [ADMIN_TARGET_USER_HEADER]: targetUserId };
5834
+ }
5835
+ async function adminGetUserHosts(targetUserId) {
5836
+ try {
5837
+ const response = await sshHostApi.get("/db/host", {
5838
+ headers: adminHeaders(targetUserId)
5839
+ });
5840
+ return Array.isArray(response.data) ? response.data : [];
5841
+ } catch (error) {
5842
+ throw handleApiError(error, "fetch user's hosts");
5843
+ }
5844
+ }
5845
+ async function adminCreateUserHost(targetUserId, hostData) {
5846
+ try {
5847
+ if (hostData.authType === "key" && hostData.key instanceof File) {
5848
+ const formData = new FormData();
5849
+ formData.append("key", hostData.key);
5850
+ const dataWithoutFile = { ...hostData, key: void 0 };
5851
+ formData.append("data", JSON.stringify(dataWithoutFile));
5852
+ const response2 = await sshHostApi.post("/db/host", formData, {
5853
+ headers: {
5854
+ "Content-Type": "multipart/form-data",
5855
+ ...adminHeaders(targetUserId)
5856
+ }
5857
+ });
5858
+ return response2.data;
5859
+ }
5860
+ const response = await sshHostApi.post("/db/host", hostData, {
5861
+ headers: adminHeaders(targetUserId)
5862
+ });
5863
+ return response.data;
5864
+ } catch (error) {
5865
+ throw handleApiError(error, "create host for user");
5866
+ }
5867
+ }
5868
+ async function adminUpdateUserHost(targetUserId, hostId, hostData) {
5869
+ try {
5870
+ if (hostData.authType === "key" && hostData.key instanceof File) {
5871
+ const formData = new FormData();
5872
+ formData.append("key", hostData.key);
5873
+ const dataWithoutFile = { ...hostData, key: void 0 };
5874
+ formData.append("data", JSON.stringify(dataWithoutFile));
5875
+ const response2 = await sshHostApi.put(`/db/host/${hostId}`, formData, {
5876
+ headers: {
5877
+ "Content-Type": "multipart/form-data",
5878
+ ...adminHeaders(targetUserId)
5879
+ }
5880
+ });
5881
+ return response2.data;
5882
+ }
5883
+ const response = await sshHostApi.put(`/db/host/${hostId}`, hostData, {
5884
+ headers: adminHeaders(targetUserId)
5885
+ });
5886
+ return response.data;
5887
+ } catch (error) {
5888
+ throw handleApiError(error, "update user's host");
5889
+ }
5890
+ }
5891
+ async function adminDeleteUserHost(targetUserId, hostId) {
5892
+ try {
5893
+ const response = await sshHostApi.delete(`/db/host/${hostId}`, {
5894
+ headers: adminHeaders(targetUserId)
5895
+ });
5896
+ return response.data;
5897
+ } catch (error) {
5898
+ throw handleApiError(error, "delete user's host");
5899
+ }
5900
+ }
5901
+ async function adminGetHostPassword(targetUserId, hostId, field = "password") {
5902
+ try {
5903
+ const response = await sshHostApi.get(
5904
+ `/db/host/${hostId}/password?field=${field}`,
5905
+ { headers: adminHeaders(targetUserId) }
5906
+ );
5907
+ return response.data?.value || null;
5908
+ } catch {
5909
+ return null;
5910
+ }
5911
+ }
5912
+ async function adminGetUserCredentials(targetUserId) {
5913
+ try {
5914
+ const response = await authApi.get("/credentials", {
5915
+ headers: adminHeaders(targetUserId)
5916
+ });
5917
+ return response.data;
5918
+ } catch (error) {
5919
+ throw handleApiError(error, "fetch user's credentials");
5920
+ }
5921
+ }
5922
+ async function adminCreateUserCredential(targetUserId, credentialData) {
5923
+ try {
5924
+ const response = await authApi.post("/credentials", credentialData, {
5925
+ headers: adminHeaders(targetUserId)
5926
+ });
5927
+ return response.data;
5928
+ } catch (error) {
5929
+ throw handleApiError(error, "create credential for user");
5930
+ }
5931
+ }
5932
+ async function adminUpdateUserCredential(targetUserId, credentialId, credentialData) {
5933
+ try {
5934
+ const response = await authApi.put(
5935
+ `/credentials/${credentialId}`,
5936
+ credentialData,
5937
+ { headers: adminHeaders(targetUserId) }
5938
+ );
5939
+ return response.data;
5940
+ } catch (error) {
5941
+ throw handleApiError(error, "update user's credential");
5942
+ }
5943
+ }
5944
+ async function adminDeleteUserCredential(targetUserId, credentialId) {
5945
+ try {
5946
+ const response = await authApi.delete(`/credentials/${credentialId}`, {
5947
+ headers: adminHeaders(targetUserId)
5948
+ });
5949
+ return response.data;
5950
+ } catch (error) {
5951
+ throw handleApiError(error, "delete user's credential");
5952
+ }
5953
+ }
5954
+
5955
+ // src/ui/api/system-status-api.ts
5956
+ init_define_import_meta_env();
5957
+ function releaseUrlFrom(info) {
5958
+ return info?.latest_release?.html_url ?? "";
5959
+ }
5960
+ async function getVersionInfo(checkRemote = true) {
5961
+ try {
5962
+ const response = await authApi.get(
5963
+ `/version${checkRemote ? "" : "?checkRemote=false"}`
4939
5964
  );
4940
5965
  return response.data;
4941
5966
  } catch (error) {
4942
5967
  handleApiError(error, "fetch version info");
4943
5968
  }
4944
5969
  }
5970
+ async function getUpdateChannel() {
5971
+ const response = await authApi.get("/version/channel");
5972
+ return response.data;
5973
+ }
5974
+ async function setUpdateChannel(channel) {
5975
+ const response = await authApi.put("/version/channel", { channel });
5976
+ return response.data;
5977
+ }
5978
+ async function getChannelReleases() {
5979
+ const response = await authApi.get("/version/releases");
5980
+ return response.data;
5981
+ }
4945
5982
  async function getDatabaseHealth() {
4946
5983
  try {
4947
5984
  const response = await authApi.get("/health");
@@ -4952,6 +5989,7 @@ async function getDatabaseHealth() {
4952
5989
  }
4953
5990
 
4954
5991
  // src/ui/api/credentials-api.ts
5992
+ init_define_import_meta_env();
4955
5993
  async function getCredentials() {
4956
5994
  try {
4957
5995
  const response = await authApi.get("/credentials");
@@ -4960,6 +5998,52 @@ async function getCredentials() {
4960
5998
  throw handleApiError(error, "fetch credentials");
4961
5999
  }
4962
6000
  }
6001
+ async function getCredentialDetails(credentialId) {
6002
+ try {
6003
+ const response = await authApi.get(`/credentials/${credentialId}`);
6004
+ return response.data;
6005
+ } catch (error) {
6006
+ throw handleApiError(error, "fetch credential details");
6007
+ }
6008
+ }
6009
+ async function createCredential(credentialData) {
6010
+ try {
6011
+ const response = await authApi.post("/credentials", credentialData);
6012
+ return response.data;
6013
+ } catch (error) {
6014
+ throw handleApiError(error, "create credential");
6015
+ }
6016
+ }
6017
+ async function updateCredential(credentialId, credentialData) {
6018
+ try {
6019
+ const response = await authApi.put(
6020
+ `/credentials/${credentialId}`,
6021
+ credentialData
6022
+ );
6023
+ return response.data;
6024
+ } catch (error) {
6025
+ throw handleApiError(error, "update credential");
6026
+ }
6027
+ }
6028
+ async function duplicateCredential(credentialId, data) {
6029
+ try {
6030
+ const response = await authApi.post(
6031
+ `/credentials/${credentialId}/duplicate`,
6032
+ data
6033
+ );
6034
+ return response.data;
6035
+ } catch (error) {
6036
+ throw handleApiError(error, "duplicate credential");
6037
+ }
6038
+ }
6039
+ async function deleteCredential(credentialId) {
6040
+ try {
6041
+ const response = await authApi.delete(`/credentials/${credentialId}`);
6042
+ return response.data;
6043
+ } catch (error) {
6044
+ throw handleApiError(error, "delete credential");
6045
+ }
6046
+ }
4963
6047
  async function getHostPassword(hostId, field = "password") {
4964
6048
  try {
4965
6049
  const response = await sshHostApi.get(
@@ -4970,8 +6054,133 @@ async function getHostPassword(hostId, field = "password") {
4970
6054
  return null;
4971
6055
  }
4972
6056
  }
6057
+ async function renameFolder(oldName, newName) {
6058
+ try {
6059
+ const response = await authApi.put("/host/folders/rename", {
6060
+ oldName,
6061
+ newName
6062
+ });
6063
+ invalidateSSHFoldersCache();
6064
+ return response.data;
6065
+ } catch (error) {
6066
+ handleApiError(error, "rename folder");
6067
+ }
6068
+ }
6069
+ async function getSSHFolders() {
6070
+ try {
6071
+ sshLogger.info("Fetching SSH folders", {
6072
+ operation: "fetch_ssh_folders"
6073
+ });
6074
+ const folders = await getCachedSSHFolders(async () => {
6075
+ const response = await authApi.get("/host/folders");
6076
+ return response.data;
6077
+ });
6078
+ sshLogger.success("SSH folders fetched successfully", {
6079
+ operation: "fetch_ssh_folders",
6080
+ count: folders.length
6081
+ });
6082
+ return folders;
6083
+ } catch (error) {
6084
+ sshLogger.error("Failed to fetch SSH folders", error, {
6085
+ operation: "fetch_ssh_folders"
6086
+ });
6087
+ handleApiError(error, "fetch SSH folders");
6088
+ throw error;
6089
+ }
6090
+ }
6091
+ async function updateFolderMetadata(name, color, icon, credentialId, localOnly) {
6092
+ try {
6093
+ sshLogger.info("Updating folder metadata", {
6094
+ operation: "update_folder_metadata",
6095
+ name,
6096
+ color,
6097
+ icon,
6098
+ credentialId
6099
+ });
6100
+ await authApi.put("/host/folders/metadata", {
6101
+ name,
6102
+ color,
6103
+ icon,
6104
+ credentialId,
6105
+ localOnly
6106
+ });
6107
+ invalidateSSHFoldersCache();
6108
+ sshLogger.success("Folder metadata updated successfully", {
6109
+ operation: "update_folder_metadata",
6110
+ name
6111
+ });
6112
+ } catch (error) {
6113
+ sshLogger.error("Failed to update folder metadata", error, {
6114
+ operation: "update_folder_metadata",
6115
+ name
6116
+ });
6117
+ handleApiError(error, "update folder metadata");
6118
+ throw error;
6119
+ }
6120
+ }
6121
+ async function reorderFolders(positions) {
6122
+ try {
6123
+ const response = await authApi.put("/host/folders/reorder", {
6124
+ positions
6125
+ });
6126
+ invalidateSSHFoldersCache();
6127
+ return response.data;
6128
+ } catch (error) {
6129
+ handleApiError(error, "reorder folders");
6130
+ throw error;
6131
+ }
6132
+ }
6133
+ async function deleteAllHostsInFolder(folderName) {
6134
+ try {
6135
+ sshLogger.info("Deleting all hosts in folder", {
6136
+ operation: "delete_folder_hosts",
6137
+ folderName
6138
+ });
6139
+ const response = await authApi.delete(
6140
+ `/host/folders/${encodeURIComponent(folderName)}/hosts`
6141
+ );
6142
+ invalidateHostsAndStatusCaches();
6143
+ sshLogger.success("All hosts in folder deleted successfully", {
6144
+ operation: "delete_folder_hosts",
6145
+ folderName,
6146
+ deletedCount: response.data.deletedCount
6147
+ });
6148
+ return response.data;
6149
+ } catch (error) {
6150
+ sshLogger.error("Failed to delete hosts in folder", error, {
6151
+ operation: "delete_folder_hosts",
6152
+ folderName
6153
+ });
6154
+ handleApiError(error, "delete hosts in folder");
6155
+ throw error;
6156
+ }
6157
+ }
6158
+ async function renameCredentialFolder(oldName, newName) {
6159
+ try {
6160
+ const response = await authApi.put("/credentials/folders/rename", {
6161
+ oldName,
6162
+ newName
6163
+ });
6164
+ invalidateSSHFoldersCache();
6165
+ return response.data;
6166
+ } catch (error) {
6167
+ throw handleApiError(error, "rename credential folder");
6168
+ }
6169
+ }
6170
+ async function reorderCredentials(positions) {
6171
+ try {
6172
+ const response = await authApi.put("/credentials/reorder", {
6173
+ positions
6174
+ });
6175
+ return response.data;
6176
+ } catch (error) {
6177
+ handleApiError(error, "reorder credentials");
6178
+ throw error;
6179
+ }
6180
+ }
4973
6181
 
4974
6182
  // src/ui/api/dashboard-api.ts
6183
+ init_define_import_meta_env();
4975
6184
  async function getUptime() {
4976
6185
  try {
4977
6186
  const response = await authApi.get("/dashboard/uptime");
@@ -5002,8 +6211,45 @@ async function logActivity(type, hostId, hostName) {
5002
6211
  throw handleApiError(error, "log activity");
5003
6212
  }
5004
6213
  }
6214
+ async function resetRecentActivity() {
6215
+ try {
6216
+ const response = await authApi.delete("/dashboard/activity/reset");
6217
+ return response.data;
6218
+ } catch (error) {
6219
+ throw handleApiError(error, "reset recent activity");
6220
+ }
6221
+ }
6222
+
6223
+ // src/ui/api/external-account-api.ts
6224
+ init_define_import_meta_env();
6225
+ async function linkExternalToPasswordAccount(externalUserId, targetUsername) {
6226
+ try {
6227
+ const response = await authApi.post("/users/link-external-to-password", {
6228
+ externalUserId,
6229
+ targetUsername
6230
+ });
6231
+ return response.data;
6232
+ } catch (error) {
6233
+ throw handleApiError(error, "link external account to password account");
6234
+ }
6235
+ }
6236
+ async function unlinkExternalFromPasswordAccount(userId) {
6237
+ try {
6238
+ const response = await authApi.post(
6239
+ "/users/unlink-external-from-password",
6240
+ { userId }
6241
+ );
6242
+ return response.data;
6243
+ } catch (error) {
6244
+ throw handleApiError(
6245
+ error,
6246
+ "unlink external sign-in from password account"
6247
+ );
6248
+ }
6249
+ }
5005
6250
 
5006
6251
  // src/ui/api/rbac-api.ts
6252
+ init_define_import_meta_env();
5007
6253
  import i18n from "i18next";
5008
6254
  async function getSharingTarget(hostId, syncId) {
5009
6255
  const api = await getConnectedRemoteApi();
@@ -5044,7 +6290,7 @@ async function updateRole(roleId, roleData) {
5044
6290
  try {
5045
6291
  const response = await rbacApi.put(`/rbac/roles/${roleId}`, roleData);
5046
6292
  if (roleData.permissions) {
5047
- const { notifyPermissionsChanged } = await import("./use-permissions-GYCBY2AU.js");
6293
+ const { notifyPermissionsChanged } = await import("./use-permissions-ISEDRY3J.js");
5048
6294
  notifyPermissionsChanged();
5049
6295
  }
5050
6296
  return response.data;
@@ -5247,14 +6493,36 @@ async function revokeCredentialAccess(credentialId, accessId) {
5247
6493
  }
5248
6494
 
5249
6495
  // src/ui/api/open-tabs-api.ts
6496
+ init_define_import_meta_env();
5250
6497
  function hasPersistableHostId(tab) {
5251
6498
  return tab.hostId == null || Number.isInteger(tab.hostId) && tab.hostId > 0;
5252
6499
  }
5253
6500
  var activeSessionsCache = createTtlRequestCache(2e3);
6501
+ async function getOpenTabs() {
6502
+ const response = await authApi.get("/open-tabs");
6503
+ return response.data;
6504
+ }
6505
+ async function deleteOpenTab(instanceId) {
6506
+ await authApi.delete(`/open-tabs/${instanceId}`);
6507
+ }
5254
6508
  async function patchOpenTab(instanceId, updates) {
5255
6509
  if (!hasPersistableHostId(updates)) return;
5256
6510
  await authApi.patch(`/open-tabs/${instanceId}`, updates);
5257
6511
  }
6512
+ async function addOpenTab(tab) {
6513
+ if (!hasPersistableHostId(tab)) return;
6514
+ await authApi.post("/open-tabs", tab);
6515
+ }
6516
+ async function getActiveSessions() {
6517
+ return activeSessionsCache.get(async () => {
6518
+ const response = await authApi.get("/open-tabs/active-sessions");
6519
+ return Array.isArray(response.data) ? response.data : [];
6520
+ });
6521
+ }
6522
+ async function getSessionTimeoutMinutes() {
6523
+ const response = await authApi.get("/open-tabs/session-timeout");
6524
+ return Number(response.data?.minutes) || 30;
6525
+ }
5258
6526
  function parseCustomKeybindings(raw) {
5259
6527
  if (!raw) return [];
5260
6528
  try {
@@ -5271,6 +6539,9 @@ async function getUserPreferences() {
5271
6539
  return response.data;
5272
6540
  });
5273
6541
  }
6542
+ async function saveUserPreferences(prefs) {
6543
+ await authApi.put("/user-preferences", prefs);
6544
+ }
5274
6545
 
5275
6546
  // src/ui/main-axios.ts
5276
6547
  var TRUST_TOKEN_KEY = "termixTrustToken";
@@ -5601,7 +6872,7 @@ function createRemoteOriginApiInstance(path) {
5601
6872
  });
5602
6873
  instance.interceptors.request.use(
5603
6874
  async (config) => {
5604
- const { getLinkedSession: getLinkedSession2 } = await import("./linked-server-UCW74T2V.js");
6875
+ const { getLinkedSession: getLinkedSession2 } = await import("./linked-server-5VFO4XQB.js");
5605
6876
  const linked = await getLinkedSession2();
5606
6877
  config.baseURL = linked ? `${linked.serverUrl}${path}` : "http://no-server-configured";
5607
6878
  if (config.headers.set) {
@@ -5790,6 +7061,17 @@ async function registerUser(username, password) {
5790
7061
  handleApiError(error, "register user");
5791
7062
  }
5792
7063
  }
7064
+ async function adminCreateUser(username, password) {
7065
+ try {
7066
+ const response = await authApi.post("/users/admin-create", {
7067
+ username,
7068
+ password
7069
+ });
7070
+ return response.data;
7071
+ } catch (error) {
7072
+ handleApiError(error, "admin create user");
7073
+ }
7074
+ }
5793
7075
  async function loginUser(username, password, rememberMe = false) {
5794
7076
  try {
5795
7077
  const response = await authApi.post("/users/login", {
@@ -5824,6 +7106,20 @@ async function requestTrustedProxyLogin() {
5824
7106
  if (response.data.success) markUserAuthenticated();
5825
7107
  return response.data;
5826
7108
  }
7109
+ async function logoutUser() {
7110
+ try {
7111
+ const response = await authApi.post("/users/logout");
7112
+ clearClientAuthState();
7113
+ userWasAuthenticated = false;
7114
+ authInvalidationHandled = false;
7115
+ return response.data;
7116
+ } catch (error) {
7117
+ clearClientAuthState();
7118
+ userWasAuthenticated = false;
7119
+ authInvalidationHandled = false;
7120
+ handleApiError(error, "logout user");
7121
+ }
7122
+ }
5827
7123
  async function getUserInfo() {
5828
7124
  try {
5829
7125
  const response = await authApi.get("/users/me");
@@ -5925,6 +7221,17 @@ async function completePasswordReset(username, tempToken, newPassword, confirmDa
5925
7221
  handleApiError(error, "complete password reset");
5926
7222
  }
5927
7223
  }
7224
+ async function changePassword(oldPassword, newPassword) {
7225
+ try {
7226
+ const response = await authApi.post("/users/change-password", {
7227
+ oldPassword,
7228
+ newPassword
7229
+ });
7230
+ return response.data;
7231
+ } catch (error) {
7232
+ handleApiError(error, "change password");
7233
+ }
7234
+ }
5928
7235
 
5929
7236
  // src/ui/lib/linked-server.ts
5930
7237
  var CACHE_MS = 6e4;
@@ -5963,6 +7270,7 @@ export {
5963
7270
  setFrontendState,
5964
7271
  getPluginRecord,
5965
7272
  knownPluginIds,
7273
+ resetPluginStore,
5966
7274
  isElectron,
5967
7275
  localBackendPort,
5968
7276
  createRegistry,
@@ -5973,6 +7281,9 @@ export {
5973
7281
  getTabType,
5974
7282
  listTabTypes,
5975
7283
  useTabTypes,
7284
+ isPersistentTabType,
7285
+ isSessionTabType,
7286
+ canRestoreTabType,
5976
7287
  tabTypeForActivity,
5977
7288
  useTabs,
5978
7289
  useTabsSafe,
@@ -5983,24 +7294,100 @@ export {
5983
7294
  dbHealthMonitor,
5984
7295
  getDeviceId,
5985
7296
  SYNC_CHANGED_EVENT,
7297
+ invalidateServerStatusCache,
7298
+ invalidateHostsAndStatusCaches,
5986
7299
  getSSHHosts,
7300
+ createSSHHost,
7301
+ updateSSHHost,
7302
+ bulkUpdateSSHHosts,
7303
+ reorderSSHHosts,
7304
+ deleteSSHHost,
5987
7305
  websocketAuthProtocols,
5988
7306
  getLinkedSession,
5989
7307
  notifySyncChanged,
5990
7308
  resolveConnectionOrigin,
5991
7309
  buildOriginWsUrl,
7310
+ getAllServerStatuses,
7311
+ getStatusCheckSettings,
7312
+ updateStatusCheckSettings,
7313
+ defaultHostRowFields,
7314
+ defaultHostSidebarPreferences,
7315
+ sanitizeHostSidebarPreferences,
7316
+ getHostSidebarPreferences,
7317
+ saveHostSidebarPreferences,
7318
+ CREDENTIAL_ROW_FIELD_KEYS,
7319
+ defaultCredentialRowFields,
7320
+ defaultCredentialSidebarPreferences,
7321
+ sanitizeCredentialSidebarPreferences,
7322
+ getCredentialSidebarPreferences,
7323
+ saveCredentialSidebarPreferences,
5992
7324
  pluginStepKey,
5993
7325
  PRESETS,
7326
+ UI_AREA_KEYS,
7327
+ getLogLevel,
7328
+ updateLogLevel,
7329
+ getSessionTimeout,
7330
+ updateSessionTimeout,
7331
+ getBranding,
5994
7332
  hydrateLocalSharedHostAuth,
7333
+ getConnectedRemoteApi,
5995
7334
  resolveRemoteHostId,
7335
+ getUserList,
7336
+ getSessions,
7337
+ revokeSession,
7338
+ revokeAllUserSessions,
7339
+ createApiKey,
7340
+ getApiKeys,
7341
+ deleteApiKey,
7342
+ makeUserAdmin,
7343
+ removeAdminStatus,
7344
+ deleteUser,
7345
+ deleteAccount,
7346
+ adminResetUserPassword,
7347
+ adminExportUserData,
7348
+ updateRegistrationAllowed,
7349
+ getExternalAutoProvision,
7350
+ updateExternalAutoProvision,
7351
+ getSecondFactorAfterExternalLogin,
7352
+ updateSecondFactorAfterExternalLogin,
7353
+ updatePasswordLoginAllowed,
5996
7354
  getPasswordResetAllowed,
7355
+ updatePasswordResetAllowed,
7356
+ adminGetUserHosts,
7357
+ adminCreateUserHost,
7358
+ adminUpdateUserHost,
7359
+ adminDeleteUserHost,
7360
+ adminGetHostPassword,
7361
+ adminGetUserCredentials,
7362
+ adminCreateUserCredential,
7363
+ adminUpdateUserCredential,
7364
+ adminDeleteUserCredential,
7365
+ releaseUrlFrom,
5997
7366
  getVersionInfo,
7367
+ getUpdateChannel,
7368
+ setUpdateChannel,
7369
+ getChannelReleases,
5998
7370
  getDatabaseHealth,
5999
7371
  getCredentials,
7372
+ getCredentialDetails,
7373
+ createCredential,
7374
+ updateCredential,
7375
+ duplicateCredential,
7376
+ deleteCredential,
6000
7377
  getHostPassword,
7378
+ renameFolder,
7379
+ getSSHFolders,
7380
+ updateFolderMetadata,
7381
+ reorderFolders,
7382
+ deleteAllHostsInFolder,
7383
+ renameCredentialFolder,
7384
+ reorderCredentials,
6001
7385
  getUptime,
6002
7386
  getRecentActivity,
6003
7387
  logActivity,
7388
+ resetRecentActivity,
7389
+ linkExternalToPasswordAccount,
7390
+ unlinkExternalFromPasswordAccount,
6004
7391
  getRoles,
6005
7392
  createRole,
6006
7393
  updateRole,
@@ -6024,21 +7411,31 @@ export {
6024
7411
  shareCredential,
6025
7412
  getCredentialAccess,
6026
7413
  revokeCredentialAccess,
7414
+ getOpenTabs,
7415
+ deleteOpenTab,
6027
7416
  patchOpenTab,
7417
+ addOpenTab,
7418
+ getActiveSessions,
7419
+ getSessionTimeoutMinutes,
6028
7420
  parseCustomKeybindings,
6029
7421
  getUserPreferences,
7422
+ saveUserPreferences,
6030
7423
  TRUST_TOKEN_KEY,
6031
7424
  setCookie,
6032
7425
  getCookie,
6033
7426
  markUserAuthenticated,
6034
7427
  getBackendUrl,
6035
7428
  createRemoteOriginApiInstance,
7429
+ hostApi,
7430
+ sshHostApi,
6036
7431
  authApi,
6037
7432
  rbacApi,
6038
7433
  handleApiError,
6039
7434
  registerUser,
7435
+ adminCreateUser,
6040
7436
  loginUser,
6041
7437
  requestTrustedProxyLogin,
7438
+ logoutUser,
6042
7439
  getUserInfo,
6043
7440
  getCurrentToken,
6044
7441
  getRegistrationAllowed,
@@ -6047,5 +7444,6 @@ export {
6047
7444
  requestDesktopAutoSession,
6048
7445
  initiatePasswordReset,
6049
7446
  verifyPasswordResetCode,
6050
- completePasswordReset
7447
+ completePasswordReset,
7448
+ changePassword
6051
7449
  };