@termix-ssh/plugin-sdk 1.0.5 → 1.0.7

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.
@@ -2,7 +2,7 @@ const __termixNoGlob = () => ({});
2
2
  import {
3
3
  hasPermission,
4
4
  usePermissions
5
- } from "./chunk-KOOUKYW3.js";
5
+ } from "./chunk-DIOJ3KW2.js";
6
6
  import {
7
7
  PRESETS,
8
8
  SYNC_CHANGED_EVENT,
@@ -39,7 +39,7 @@ import {
39
39
  usePluginStore,
40
40
  useTabTypes,
41
41
  websocketAuthProtocols
42
- } from "./chunk-OEOKIKXC.js";
42
+ } from "./chunk-NZG6HNQH.js";
43
43
  import {
44
44
  __export,
45
45
  define_import_meta_env_default
@@ -49010,7 +49010,9 @@ var docs_pages_default = {
49010
49010
  pluginCatalog: "plugins",
49011
49011
  cli: "cli",
49012
49012
  develop: "develop",
49013
- communityRegistry: "develop/community-registry"
49013
+ communityRegistry: "develop/community-registry",
49014
+ pluginRegistries: "guide/plugins#registries",
49015
+ hostRegistry: "develop/registries"
49014
49016
  };
49015
49017
 
49016
49018
  // src/ui/lib/docs.ts
@@ -49233,7 +49235,7 @@ function withAnchor(url, anchor) {
49233
49235
  }
49234
49236
 
49235
49237
  // src/ui/components/panel-layout.tsx
49236
- import { Children as Children5, Fragment as Fragment11, useRef as useRef28 } from "react";
49238
+ import { Children as Children5, Fragment as Fragment11, isValidElement as isValidElement2, useRef as useRef28 } from "react";
49237
49239
  import { useTranslation as useTranslation3 } from "react-i18next";
49238
49240
  import { Fragment as Fragment12, jsx as jsx31, jsxs as jsxs8 } from "react/jsx-runtime";
49239
49241
  var PANEL = {
@@ -49516,11 +49518,16 @@ function ToggleButton({
49516
49518
  }
49517
49519
  );
49518
49520
  }
49521
+ function flattenFacts(children) {
49522
+ return Children5.toArray(children).flatMap(
49523
+ (child) => isValidElement2(child) && child.type === Fragment11 ? flattenFacts(child.props.children) : [child]
49524
+ );
49525
+ }
49519
49526
  function Facts({
49520
49527
  className,
49521
49528
  children
49522
49529
  }) {
49523
- const items = Children5.toArray(children).filter(Boolean);
49530
+ const items = flattenFacts(children);
49524
49531
  if (items.length === 0) return null;
49525
49532
  return /* @__PURE__ */ jsx31("span", { className: cn("flex min-w-0 items-center gap-2", className), children: items.map((child, i) => /* @__PURE__ */ jsxs8(Fragment11, { children: [
49526
49533
  i > 0 && /* @__PURE__ */ jsx31("span", { "aria-hidden": true, className: "h-3 w-px shrink-0 bg-border" }),
@@ -50568,6 +50575,37 @@ var en_default = {
50568
50575
  desktopLinked: "Linked to {{server}}",
50569
50576
  pluginsDocsLink: "Read about each one"
50570
50577
  },
50578
+ desktopUpdates: {
50579
+ title: "Desktop app",
50580
+ mode: "Updates",
50581
+ modeHint: "How this app gets new versions.",
50582
+ manualModeHint: "This copy can not update itself, so Termix only tells you when a new version is out.",
50583
+ modeAutomatic: "Automatic",
50584
+ modePrompt: "Ask first",
50585
+ modeNever: "Never",
50586
+ automaticBody: "Download new versions in the background and install them when you restart.",
50587
+ promptBody: "Tell me when a new version is out and let me choose when to download it.",
50588
+ neverBody: "Do not check for updates. You can still check by hand in Settings.",
50589
+ onboardingTitle: "App updates",
50590
+ onboardingBody: "The desktop app can now update itself. Pick how you want new versions to arrive. You can change this later in Settings, Updates.",
50591
+ onboardingManual: "This copy of the app was installed in a way that can not update itself, so Termix will tell you when a new version is out with a link to download it.",
50592
+ status: "Version {{version}}",
50593
+ statusIdle: "Not checked yet",
50594
+ statusChecking: "Checking for updates",
50595
+ statusAvailable: "Version {{version}} is available",
50596
+ statusDownloading: "Downloading {{version}} ({{progress}}%)",
50597
+ statusReady: "Version {{version}} is ready. Restart to install it.",
50598
+ statusUpToDate: "You have the newest version",
50599
+ statusError: "Could not check for updates. Try again later.",
50600
+ checkNow: "Check now",
50601
+ download: "Download",
50602
+ restart: "Restart now",
50603
+ later: "Later",
50604
+ available: "Termix {{version}} is available",
50605
+ manualHint: "Download it from the release page and install it over this one.",
50606
+ ready: "Termix {{version}} is ready to install",
50607
+ readyHint: "It installs the next time Termix restarts."
50608
+ },
50571
50609
  nav: {
50572
50610
  home: "Home",
50573
50611
  terminal: "Terminal",
@@ -50615,7 +50653,8 @@ var en_default = {
50615
50653
  },
50616
50654
  searchEverything: "Search hosts, tabs and actions",
50617
50655
  search: "Search",
50618
- hiddenCount: "{{count}} hidden",
50656
+ hiddenCount_one: "{{count}} hidden",
50657
+ hiddenCount_other: "{{count}} hidden",
50619
50658
  showInRail: "Show in sidebar",
50620
50659
  moveUp: "Move up",
50621
50660
  moveDown: "Move down",
@@ -50679,7 +50718,8 @@ var en_default = {
50679
50718
  unsavedChangesDescription: "Your host changes have not been saved. Discard them?",
50680
50719
  keepEditing: "Keep editing",
50681
50720
  discardChanges: "Discard changes",
50682
- movedToFolder: 'Moved {{count}} host(s) to "{{folder}}"',
50721
+ movedToFolder_one: 'Moved {{count}} host to "{{folder}}"',
50722
+ movedToFolder_other: 'Moved {{count}} hosts to "{{folder}}"',
50683
50723
  editHostTooltip: "Edit host",
50684
50724
  behavior: "Behavior",
50685
50725
  scrollbackBuffer: "Scrollback Buffer",
@@ -50880,7 +50920,8 @@ var en_default = {
50880
50920
  collapseSubHosts: "Collapse sub-hosts",
50881
50921
  expandSubHosts: "Expand sub-hosts",
50882
50922
  cannotNestUnderDescendant: "Can't nest a host under its own sub-host",
50883
- movedToParent: 'Moved {{count}} host(s) under "{{parent}}"',
50923
+ movedToParent_one: 'Moved {{count}} host under "{{parent}}"',
50924
+ movedToParent_other: 'Moved {{count}} hosts under "{{parent}}"',
50884
50925
  newFolder: "New folder",
50885
50926
  createFolderTitle: "Create folder",
50886
50927
  editFolderTitle: "Edit folder",
@@ -50908,7 +50949,8 @@ var en_default = {
50908
50949
  folderSaved: "Folder saved",
50909
50950
  failedToSaveFolder: "Failed to save folder",
50910
50951
  folderDeleted: 'Deleted folder "{{name}}"',
50911
- deleteFolderConfirm: 'Delete "{{name}}" and its {{count}} host(s)? This cannot be undone.',
50952
+ deleteFolderConfirm_one: 'Delete "{{name}}" and its {{count}} host? This cannot be undone.',
50953
+ deleteFolderConfirm_other: 'Delete "{{name}}" and its {{count}} hosts? This cannot be undone.',
50912
50954
  failedToMoveHosts: "Failed to move hosts",
50913
50955
  failedToReorder: "Failed to reorder",
50914
50956
  expandAll: "Expand all folders",
@@ -50944,6 +50986,8 @@ var en_default = {
50944
50986
  actionsClick: "Click to expand/collapse",
50945
50987
  openOnDoubleClick: "Open on double click",
50946
50988
  openOnDoubleClickDesc: "Require a double click to open a host session instead of a single click",
50989
+ closeOnOpen: "Hide sidebar after opening",
50990
+ closeOnOpenDesc: "Close the sidebar after you open a host from it",
50947
50991
  showFolderPaths: "Show folder paths",
50948
50992
  showFolderPathsDesc: "Show the parent folder path above nested subfolder names. Subfolders stay indented either way.",
50949
50993
  rowDetailsTitle: "Row details",
@@ -50976,7 +51020,8 @@ var en_default = {
50976
51020
  copyLink: "Copy Link",
50977
51021
  deleteCredentialConfirm: 'Delete credential "{{name}}"?',
50978
51022
  deletedCredential: "Deleted {{name}}",
50979
- deleteHostsConfirm: "Delete {{count}} host{{plural}}? This cannot be undone.",
51023
+ deleteHostsConfirm_one: "Delete {{count}} host? This cannot be undone.",
51024
+ deleteHostsConfirm_other: "Delete {{count}} hosts? This cannot be undone.",
50980
51025
  movedToRoot: "Moved to root",
50981
51026
  addTagsPlaceholder: "Add tags...",
50982
51027
  authDetails: "Authentication Details",
@@ -51035,7 +51080,8 @@ var en_default = {
51035
51080
  groupFeatureFlags: "Plugin settings",
51036
51081
  groupAdvanced: "Advanced config",
51037
51082
  preview: "Preview",
51038
- moreHosts: "... {{count}} more hosts",
51083
+ moreHosts_one: "... {{count}} more host",
51084
+ moreHosts_other: "... {{count}} more hosts",
51039
51085
  summary: "{{selected}} of {{total}} hosts",
51040
51086
  credentialsIncluded: "credentials included",
51041
51087
  credentialsExcluded: "credentials excluded",
@@ -51048,16 +51094,20 @@ var en_default = {
51048
51094
  sampleDownloaded: "Sample file downloaded",
51049
51095
  failedToDeleteCredential2: "Failed to delete credential",
51050
51096
  noFolderOption: "(No folder)",
51051
- nSelected: "{{count}} selected",
51097
+ nSelected_one: "{{count}} selected",
51098
+ nSelected_other: "{{count}} selected",
51052
51099
  featuresMenu: "Plugins",
51053
51100
  moveMenu: "Move",
51054
51101
  connectSelected: "Connect",
51055
51102
  cancelSelection: "Cancel",
51056
- deletedCount: "Deleted {{count}} hosts",
51057
- failedToDeleteCount: "Failed to delete {{count}} hosts",
51103
+ deletedCount_one: "Deleted {{count}} host",
51104
+ deletedCount_other: "Deleted {{count}} hosts",
51105
+ failedToDeleteCount_one: "Failed to delete {{count}} host",
51106
+ failedToDeleteCount_other: "Failed to delete {{count}} hosts",
51058
51107
  duplicatedHost: 'Duplicated "{{name}}"',
51059
51108
  failedToDuplicateHost: "Failed to duplicate host",
51060
- updatedCount: "Updated {{count}} hosts",
51109
+ updatedCount_one: "Updated {{count}} host",
51110
+ updatedCount_other: "Updated {{count}} hosts",
51061
51111
  friendlyNameLabel: "Friendly Name",
51062
51112
  descriptionLabel: "Description",
51063
51113
  loadingHosts: "Loading hosts...",
@@ -51097,7 +51147,8 @@ var en_default = {
51097
51147
  shareHostTitle: "Share: {{name}}",
51098
51148
  shareFolder: "Share Folder",
51099
51149
  shareFolderTitle: "Share folder: {{name}}",
51100
- folderSharedSuccessfully: "Shared {{count}} host(s) in folder",
51150
+ folderSharedSuccessfully_one: "Shared {{count}} host in folder",
51151
+ folderSharedSuccessfully_other: "Shared {{count}} hosts in folder",
51101
51152
  failedToShareFolder: "Failed to share folder",
51102
51153
  sharing: {
51103
51154
  loadError: "Failed to load sharing data. Please try again.",
@@ -51256,7 +51307,8 @@ var en_default = {
51256
51307
  unsplit: "Unsplit",
51257
51308
  layouts: "Layouts",
51258
51309
  applyLayout: "Change layout",
51259
- maxPanes: "A split can hold up to {{count}} panes",
51310
+ maxPanes_one: "A split can hold up to {{count}} pane",
51311
+ maxPanes_other: "A split can hold up to {{count}} panes",
51260
51312
  dropSplit: "Drop to split",
51261
51313
  dropHere: "Drop to show here",
51262
51314
  paneActions: "Pane actions",
@@ -51389,7 +51441,7 @@ var en_default = {
51389
51441
  acceptNewKey: "Accept New Key & Continue"
51390
51442
  },
51391
51443
  errors: {
51392
- databaseConnection: "Could not connect to the database",
51444
+ databaseConnection: "The Termix server is not responding",
51393
51445
  embeddedServerFailed: "Termix's local server could not start",
51394
51446
  unknownError: "Unknown error",
51395
51447
  syncedHostMissing: "The synced host does not exist on the linked server",
@@ -51414,11 +51466,12 @@ var en_default = {
51414
51466
  sessionExpiredLogin: "Session expired. Please log in again."
51415
51467
  },
51416
51468
  messages: {
51417
- registrationDisabled: "New account registration is currently disabled by an admin. Please log in or contact an administrator.",
51469
+ registrationDisabled: "You have no Termix account yet. Ask an admin to turn on Auto-create external accounts.",
51418
51470
  userNotAllowed: "Your account is not authorized to register. Please contact an administrator.",
51419
- databaseConnectionFailed: "Failed to connect to the database server",
51471
+ databaseConnectionFailed: "It may still be starting, or it stopped. This page keeps trying and continues on its own once the server is back.",
51420
51472
  embeddedServerPortInUse: "Port {{port}} is already in use by another program. This is usually a Termix Docker container or a leftover Termix process from a previous session. Close it, then restart Termix.",
51421
51473
  embeddedServerPortInUseUnknownPort: "One of the ports Termix needs is already in use by another program. Close whatever is using it, then restart Termix.",
51474
+ embeddedServerOldDatabase: "Your local data is from Termix 2.8 or older and has to pass through 2.9 first. Install Termix 2.9.1, open it once so it can move your data, then update to this version again.",
51422
51475
  embeddedServerCrashed: "The local server stopped unexpectedly. Restart Termix, and check the desktop log if this keeps happening.",
51423
51476
  resetCodeSent: "Reset code sent to Docker logs",
51424
51477
  codeVerified: "Code verified successfully",
@@ -51553,7 +51606,7 @@ var en_default = {
51553
51606
  allowPasswordLogin: "Allow Password Login",
51554
51607
  allowPasswordLoginDesc: "Username/password login",
51555
51608
  externalAutoProvision: "Auto-create external accounts",
51556
- externalAutoProvisionDesc: "Create an account the first time someone signs in through an external login such as SSO or LDAP, even when registration is off",
51609
+ externalAutoProvisionDesc: "Create an account the first time someone signs in through an external login such as SSO or LDAP. When off, only people who already have an account can sign in that way",
51557
51610
  secondFactorAfterExternalLogin: "Ask for a second factor after external logins (SSO, GitHub, Google, LDAP)",
51558
51611
  secondFactorAfterExternalLoginDesc: "Off, an enrolled second factor is only asked for after password and other local logins, same as before. On, it is asked for after every login method, including SSO and LDAP.",
51559
51612
  allowPasswordReset: "Allow Password Reset",
@@ -51572,7 +51625,8 @@ var en_default = {
51572
51625
  statusCheck: "Status Check",
51573
51626
  sec: "sec",
51574
51627
  logLevel: "Log Level",
51575
- usersCount: "{{count}} users",
51628
+ usersCount_one: "{{count}} user",
51629
+ usersCount_other: "{{count}} users",
51576
51630
  searchUsers: "Search users...",
51577
51631
  noUsers: "No users",
51578
51632
  noUsersMatch: "No users match your search",
@@ -51582,7 +51636,8 @@ var en_default = {
51582
51636
  roleName: "Name",
51583
51637
  roleDisplayName: "Display Name",
51584
51638
  roleDescription: "Description",
51585
- rolesCount: "{{count}} roles",
51639
+ rolesCount_one: "{{count}} role",
51640
+ rolesCount_other: "{{count}} roles",
51586
51641
  createRole: "Create",
51587
51642
  creating: "Creating...",
51588
51643
  exportDatabase: "Export Database",
@@ -51596,7 +51651,8 @@ var en_default = {
51596
51651
  changeFile: "Change",
51597
51652
  import: "Import",
51598
51653
  importing: "Importing...",
51599
- apiKeysCount: "{{count}} keys",
51654
+ apiKeysCount_one: "{{count}} key",
51655
+ apiKeysCount_other: "{{count}} keys",
51600
51656
  apiKeysDocsLink: "View docs",
51601
51657
  apiKeysCliHint: "Use an API key with the Termix CLI to manage servers from your terminal.",
51602
51658
  apiKeysCliLink: "View CLI docs",
@@ -51618,7 +51674,8 @@ var en_default = {
51618
51674
  systemBadge: "SYS",
51619
51675
  customBadge: "CUSTOM",
51620
51676
  youBadge: "YOU",
51621
- sessionsActive: "{{count}} active",
51677
+ sessionsActive_one: "{{count}} active",
51678
+ sessionsActive_other: "{{count}} active",
51622
51679
  sessionActive: "Active: {{time}}",
51623
51680
  sessionExpires: "Exp: {{time}}",
51624
51681
  revokeAll: "All",
@@ -51727,14 +51784,16 @@ var en_default = {
51727
51784
  exportUserDataDesc: "Download this user's hosts, credentials and file manager data as JSON. Secrets are decrypted.",
51728
51785
  exportUserDataSuccess: "User data exported",
51729
51786
  exportUserDataFailed: "Failed to export user data",
51730
- hostsCount: "{{count}} hosts",
51787
+ hostsCount_one: "{{count}} host",
51788
+ hostsCount_other: "{{count}} hosts",
51731
51789
  addHostForUser: "Add Host",
51732
51790
  noHostsForUser: "This user has no hosts",
51733
51791
  connectToHost: "Connect",
51734
51792
  deleteHostConfirm: 'Delete host "{{name}}" belonging to {{username}}?',
51735
51793
  hostDeletedSuccess: "Host deleted",
51736
51794
  hostDeleteFailed: "Failed to delete host",
51737
- credentialsCount: "{{count}} credentials",
51795
+ credentialsCount_one: "{{count}} credential",
51796
+ credentialsCount_other: "{{count}} credentials",
51738
51797
  addCredentialForUser: "Add Credential",
51739
51798
  noCredentialsForUser: "This user has no credentials",
51740
51799
  deleteCredentialConfirm: 'Delete credential "{{name}}" belonging to {{username}}?',
@@ -51763,7 +51822,8 @@ var en_default = {
51763
51822
  importError: "Database import failed",
51764
51823
  sectionHostDefaults: "Host Defaults",
51765
51824
  rolePermissions: {
51766
- count: "{{count}} permissions",
51825
+ count_one: "{{count}} permission",
51826
+ count_other: "{{count}} permissions",
51767
51827
  editAction: "Edit permissions",
51768
51828
  loadError: "Failed to load the permissions catalog",
51769
51829
  saved: "Role permissions saved",
@@ -51982,7 +52042,8 @@ var en_default = {
51982
52042
  apiKeyCreatedWarning: "Key created - copy it now, it won't be shown again.",
51983
52043
  copyApiKey: "Copy API key",
51984
52044
  copiedToClipboard: "Copied to clipboard",
51985
- apiKeyCount: "{{count}} keys",
52045
+ apiKeyCount_one: "{{count}} key",
52046
+ apiKeyCount_other: "{{count}} keys",
51986
52047
  newKey: "New Key",
51987
52048
  noApiKeys: "No API keys yet.",
51988
52049
  apiKeyActive: "Active",
@@ -52183,25 +52244,42 @@ var en_default = {
52183
52244
  tabs: {
52184
52245
  installed: "Installed",
52185
52246
  browse: "Browse",
52186
- updates: "Updates"
52247
+ updates: "Updates",
52248
+ registries: "Registries"
52187
52249
  },
52188
52250
  status: {
52189
52251
  summary: "{{installed}} installed, {{running}} running",
52190
52252
  running: "Running",
52191
52253
  disabled: "Disabled",
52192
52254
  failed: "Stopped unexpectedly",
52193
- blocked: "Waiting on another plugin"
52255
+ blocked: "Waiting on another plugin",
52256
+ server: "Runs on your server"
52194
52257
  },
52195
52258
  groups: {
52196
52259
  running: "Running",
52197
- notRunning: "Not running"
52260
+ notRunning: "Not running",
52261
+ onServer: "On your server"
52198
52262
  },
52263
+ runsOnServerHint: "This plugin only runs on your server, so it stays off in the desktop app. It still works there.",
52199
52264
  sort: {
52200
52265
  popular: "Most popular",
52201
52266
  name: "Name",
52202
52267
  updated: "Recently updated",
52203
52268
  category: "Category"
52204
52269
  },
52270
+ columns: {
52271
+ title: "Columns",
52272
+ auto: "Auto",
52273
+ count: "{{count}} wide"
52274
+ },
52275
+ table: {
52276
+ name: "Name",
52277
+ description: "Description",
52278
+ version: "Version",
52279
+ status: "Status",
52280
+ category: "Category",
52281
+ downloads: "Downloads"
52282
+ },
52205
52283
  risk: {
52206
52284
  critical: "Critical",
52207
52285
  high: "High risk",
@@ -52233,6 +52311,7 @@ var en_default = {
52233
52311
  syncEntities_other: "Desktop sync"
52234
52312
  },
52235
52313
  consent: {
52314
+ enableTitle: "Enable {{name}}?",
52236
52315
  installTitle: "Install {{name}}",
52237
52316
  updateTitle: "Update {{name}}",
52238
52317
  agreeUpdate: "Agree and update",
@@ -52352,8 +52431,47 @@ var en_default = {
52352
52431
  noneInstalled: "No plugins installed yet. Browse to add some.",
52353
52432
  nothingHere: "Nothing here.",
52354
52433
  nothingHereHint: "Try another category or search.",
52355
- communitySoon: "Community plugins are coming in a later update. Plugin authors can already submit theirs to the community registry.",
52434
+ showInstalled: "Show installed",
52435
+ allInstalled: "Everything here is already installed.",
52436
+ allInstalledHint: "Turn on Show installed to see them.",
52356
52437
  communitySubmit: "How to submit",
52438
+ registries: {
52439
+ intro: "Registries are lists of plugins you can install. The official one is always on. You can turn on the community registry or add your own.",
52440
+ hostYourOwn: "Host your own registry",
52441
+ add: "Add registry",
52442
+ addTitle: "Add a registry",
52443
+ addHint: "Paste the link to the registry's index.json. Termix reads it and shows the key it signs plugins with. Only add registries from people you trust.",
52444
+ urlLabel: "Index URL",
52445
+ check: "Check",
52446
+ addConfirm: "Trust and add",
52447
+ added: "Added {{name}}",
52448
+ customWarning: "Plugins from this registry are not reviewed by the Termix team. Only the owner of the registry decides what is in it. Every download must be signed by the key above.",
52449
+ keyFingerprint: "Key {{keyId}}",
52450
+ pluginCount_one: "{{count}} plugin",
52451
+ pluginCount_other: "{{count}} plugins",
52452
+ officialName: "Official",
52453
+ communityName: "Community",
52454
+ alwaysOn: "Always on",
52455
+ communityHint: "Plugins made by other people. Each version is checked by a person and by automated checks before it is listed.",
52456
+ communityConfirmTitle: "Turn on community plugins?",
52457
+ communityConfirmBody: "Community plugins are made by other people, not the Termix team. Every version is checked by a person and by automated checks before it is listed, but mistakes can still get through. Only install plugins you trust and check what each one asks for.",
52458
+ communityConfirm: "Turn on",
52459
+ communityBadge: "Community",
52460
+ communityBadgeHint: "From the community registry. Made by other people and reviewed before it was listed.",
52461
+ customBadge: "Custom",
52462
+ customBadgeHint: "From {{name}}, a registry an admin added. Not reviewed by the Termix team.",
52463
+ remove: "Remove",
52464
+ removeTitle: "Remove {{name}}?",
52465
+ removeBody: "Its plugins will no longer show in Browse. You can add it again later.",
52466
+ removed: "Removed {{name}}",
52467
+ inUse: "Uninstall the plugins from {{name}} first: {{list}}",
52468
+ changeFailed: "Could not change the registry: {{error}}",
52469
+ loadFailed: "Could not load registries: {{error}}",
52470
+ unreachable: "Could not read it: {{error}}",
52471
+ filter: "Registry",
52472
+ allRegistries: "All registries",
52473
+ browseHint: "Turn on community plugins or add your own registry in the Registries tab."
52474
+ },
52357
52475
  upToDate: "Everything is up to date.",
52358
52476
  lastChecked: "Last checked {{time}}",
52359
52477
  updatesReady_one: "{{count}} update ready.",
@@ -52376,11 +52494,8 @@ var en_default = {
52376
52494
  signedOnly: "TERMIX_REQUIRE_SIGNED_PLUGINS is set, so installing from a file stays blocked."
52377
52495
  },
52378
52496
  count: {
52379
- active_one: "{{formatted}} active install",
52380
- active_other: "{{formatted}} active installs",
52381
52497
  downloads_one: "{{formatted}} download",
52382
52498
  downloads_other: "{{formatted}} downloads",
52383
- activeHint: "Instances that reported this plugin turned on in the last week. Instances with usage statistics turned off are not counted.",
52384
52499
  downloadsHint: "How many times a release was downloaded. This is not the number of installs."
52385
52500
  },
52386
52501
  unverified: "Unverified",
@@ -52555,7 +52670,12 @@ var en_default = {
52555
52670
  dashboardServiceLinks: "Service links",
52556
52671
  homepageItems: "Homepage items",
52557
52672
  networkTopology: "Network map",
52558
- workspaces: "Workspaces"
52673
+ workspaces: "Workspaces",
52674
+ hostDefaults: "Host defaults",
52675
+ hostDefaultsAdmin: "Server host defaults",
52676
+ aiProviders: "AI providers",
52677
+ homepageLayouts: "Homepage layouts",
52678
+ accountProfile: "Account profile"
52559
52679
  },
52560
52680
  proxy: {
52561
52681
  title: "Reverse proxy",
@@ -52602,9 +52722,11 @@ var en_default = {
52602
52722
  continue: "Continue",
52603
52723
  back: "Back",
52604
52724
  mergeTitle: "Add it to my account",
52605
- mergeBody: "The {{count}} items on this device are added to your account. Items your account already has stay as they are on the server.",
52725
+ mergeBody_one: "The item on this device is added to your account. Items your account already has stay as they are on the server.",
52726
+ mergeBody_other: "The {{count}} items on this device are added to your account. Items your account already has stay as they are on the server.",
52606
52727
  replaceTitle: "Replace it with my account",
52607
- replaceBody: "The {{count}} items on this device are removed, and this device takes everything from your account. Hosts kept on this device only stay.",
52728
+ replaceBody_one: "The item on this device is removed, and this device takes everything from your account. Hosts kept on this device only stay.",
52729
+ replaceBody_other: "The {{count}} items on this device are removed, and this device takes everything from your account. Hosts kept on this device only stay.",
52608
52730
  link: "Link",
52609
52731
  linking: "Linking and running the first sync...",
52610
52732
  linked: "Linked. Your data is syncing now.",
@@ -52704,46 +52826,131 @@ var en_default = {
52704
52826
  pickCredential: "Pick a credential to edit",
52705
52827
  pickDefaults: "Pick a level of defaults to edit",
52706
52828
  pickHint: "Everything about a connection lives here, grouped so you can find it."
52829
+ },
52830
+ rbac: {
52831
+ roles: {
52832
+ admin: "Admin",
52833
+ user: "User"
52834
+ }
52707
52835
  }
52708
52836
  };
52709
52837
 
52838
+ // src/ui/locales/languages.json
52839
+ var languages_default = [
52840
+ { code: "af", file: "af_ZA", name: "Afrikaans", label: "Afrikaans" },
52841
+ { code: "ar", file: "ar_SA", name: "Arabic", label: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629" },
52842
+ { code: "bn", file: "bn_BD", name: "Bengali", label: "\u09AC\u09BE\u0982\u09B2\u09BE" },
52843
+ { code: "bg", file: "bg_BG", name: "Bulgarian", label: "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438" },
52844
+ { code: "ca", file: "ca_ES", name: "Catalan", label: "Catal\xE0" },
52845
+ {
52846
+ code: "zh-CN",
52847
+ file: "zh_CN",
52848
+ name: "Simplified Chinese",
52849
+ label: "\u4E2D\u6587 (\u7B80\u4F53)"
52850
+ },
52851
+ {
52852
+ code: "zh-TW",
52853
+ file: "zh_TW",
52854
+ name: "Traditional Chinese (Taiwan)",
52855
+ label: "\u4E2D\u6587 (\u7E41\u9AD4)"
52856
+ },
52857
+ { code: "hr", file: "hr_HR", name: "Croatian", label: "Hrvatski" },
52858
+ { code: "cs", file: "cs_CZ", name: "Czech", label: "\u010Ce\u0161tina" },
52859
+ { code: "da", file: "da_DK", name: "Danish", label: "Dansk" },
52860
+ { code: "nl", file: "nl_NL", name: "Dutch", label: "Nederlands" },
52861
+ { code: "et", file: "et_EE", name: "Estonian", label: "Eesti" },
52862
+ { code: "fi", file: "fi_FI", name: "Finnish", label: "Suomi" },
52863
+ { code: "fr", file: "fr_FR", name: "French", label: "Fran\xE7ais" },
52864
+ { code: "de", file: "de_DE", name: "German", label: "Deutsch" },
52865
+ { code: "el", file: "el_GR", name: "Greek", label: "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC" },
52866
+ { code: "he", file: "he_IL", name: "Hebrew", label: "\u05E2\u05D1\u05E8\u05D9\u05EA" },
52867
+ { code: "hi", file: "hi_IN", name: "Hindi", label: "\u0939\u093F\u0928\u094D\u0926\u0940" },
52868
+ { code: "hu", file: "hu_HU", name: "Hungarian", label: "Magyar" },
52869
+ {
52870
+ code: "id",
52871
+ file: "id_ID",
52872
+ name: "Indonesian",
52873
+ label: "Indonesia"
52874
+ },
52875
+ { code: "it", file: "it_IT", name: "Italian", label: "Italiano" },
52876
+ { code: "ja", file: "ja_JP", name: "Japanese", label: "\u65E5\u672C\u8A9E" },
52877
+ { code: "ko", file: "ko_KR", name: "Korean", label: "\uD55C\uAD6D\uC5B4" },
52878
+ { code: "lv", file: "lv_LV", name: "Latvian", label: "Latvie\u0161u" },
52879
+ {
52880
+ code: "lt",
52881
+ file: "lt_LT",
52882
+ name: "Lithuanian",
52883
+ label: "Lietuvi\u0173"
52884
+ },
52885
+ { code: "ms", file: "ms_MY", name: "Malay", label: "Bahasa Melayu" },
52886
+ {
52887
+ code: "no",
52888
+ file: "no_NO",
52889
+ name: "Norwegian Bokm\xE5l",
52890
+ label: "Norsk"
52891
+ },
52892
+ { code: "pl", file: "pl_PL", name: "Polish", label: "Polski" },
52893
+ {
52894
+ code: "pt-PT",
52895
+ file: "pt_PT",
52896
+ name: "European Portuguese",
52897
+ label: "Portugu\xEAs (PT)"
52898
+ },
52899
+ {
52900
+ code: "pt-BR",
52901
+ file: "pt_BR",
52902
+ name: "Brazilian Portuguese",
52903
+ label: "Portugu\xEAs (BR)"
52904
+ },
52905
+ { code: "ro", file: "ro_RO", name: "Romanian", label: "Rom\xE2n\u0103" },
52906
+ { code: "ru", file: "ru_RU", name: "Russian", label: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439" },
52907
+ {
52908
+ code: "sr",
52909
+ file: "sr_SP",
52910
+ name: "Serbian (Cyrillic script)",
52911
+ label: "\u0421\u0440\u043F\u0441\u043A\u0438"
52912
+ },
52913
+ { code: "sk", file: "sk_SK", name: "Slovak", label: "Sloven\u010Dina" },
52914
+ {
52915
+ code: "sl",
52916
+ file: "sl_SI",
52917
+ name: "Slovenian",
52918
+ label: "Sloven\u0161\u010Dina"
52919
+ },
52920
+ {
52921
+ code: "es-ES",
52922
+ file: "es_ES",
52923
+ name: "Spanish (Spain)",
52924
+ label: "Espa\xF1ol"
52925
+ },
52926
+ { code: "sv-SE", file: "sv_SE", name: "Swedish", label: "Svenska" },
52927
+ { code: "th", file: "th_TH", name: "Thai", label: "\u0E44\u0E17\u0E22" },
52928
+ { code: "tr", file: "tr_TR", name: "Turkish", label: "T\xFCrk\xE7e" },
52929
+ {
52930
+ code: "uk",
52931
+ file: "uk_UA",
52932
+ name: "Ukrainian",
52933
+ label: "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"
52934
+ },
52935
+ {
52936
+ code: "vi",
52937
+ file: "vi_VN",
52938
+ name: "Vietnamese",
52939
+ label: "Ti\u1EBFng Vi\u1EC7t"
52940
+ }
52941
+ ];
52942
+
52943
+ // src/ui/i18n/languages.ts
52944
+ var TRANSLATED_LANGUAGES = languages_default;
52945
+ var LANGUAGES = [
52946
+ { code: "en", label: "English" },
52947
+ ...TRANSLATED_LANGUAGES.map(({ code, label }) => ({ code, label }))
52948
+ ];
52949
+
52710
52950
  // src/ui/i18n/i18n.ts
52711
- var LOCALE_FILES = {
52712
- af: "af_ZA",
52713
- ar: "ar_SA",
52714
- bn: "bn_BD",
52715
- bg: "bg_BG",
52716
- ca: "ca_ES",
52717
- cs: "cs_CZ",
52718
- da: "da_DK",
52719
- de: "de_DE",
52720
- el: "el_GR",
52721
- "es-ES": "es_ES",
52722
- fi: "fi_FI",
52723
- fr: "fr_FR",
52724
- he: "he_IL",
52725
- hi: "hi_IN",
52726
- hu: "hu_HU",
52727
- id: "id_ID",
52728
- it: "it_IT",
52729
- ja: "ja_JP",
52730
- ko: "ko_KR",
52731
- nl: "nl_NL",
52732
- no: "no_NO",
52733
- pl: "pl_PL",
52734
- "pt-PT": "pt_PT",
52735
- "pt-BR": "pt_BR",
52736
- ro: "ro_RO",
52737
- ru: "ru_RU",
52738
- sr: "sr_SP",
52739
- "sv-SE": "sv_SE",
52740
- th: "th_TH",
52741
- tr: "tr_TR",
52742
- uk: "uk_UA",
52743
- vi: "vi_VN",
52744
- "zh-CN": "zh_CN",
52745
- "zh-TW": "zh_TW"
52746
- };
52951
+ var LOCALE_FILES = Object.fromEntries(
52952
+ TRANSLATED_LANGUAGES.map(({ code, file }) => [code, file])
52953
+ );
52747
52954
  var translatedFiles = __termixNoGlob(
52748
52955
  "../locales/translated/*.json"
52749
52956
  );
@@ -52771,8 +52978,16 @@ function normalizeLanguageCode(language) {
52771
52978
  (supported) => supported.toLowerCase() === normalized.toLowerCase()
52772
52979
  );
52773
52980
  if (exactMatch) return exactMatch;
52774
- const baseLanguage = normalized.split("-")[0];
52775
- return supportedLngs.includes(baseLanguage) ? baseLanguage : "en";
52981
+ const baseLanguage = normalized.split("-")[0].toLowerCase();
52982
+ if (supportedLngs.includes(baseLanguage)) return baseLanguage;
52983
+ if (baseLanguage === "zh") {
52984
+ return /-(tw|hk|mo|hant)\b/i.test(normalized) ? "zh-TW" : "zh-CN";
52985
+ }
52986
+ if (baseLanguage === "nb" || baseLanguage === "nn") return "no";
52987
+ if (baseLanguage === "pt") return "pt-BR";
52988
+ return supportedLngs.find(
52989
+ (supported) => supported.toLowerCase().startsWith(`${baseLanguage}-`)
52990
+ ) ?? "en";
52776
52991
  }
52777
52992
  var localeBackend = {
52778
52993
  type: "backend",
@@ -53342,6 +53557,20 @@ function pluginApiFor(pluginId, origin, local) {
53342
53557
  }
53343
53558
  return client;
53344
53559
  }
53560
+ async function fetchSocketTicket() {
53561
+ const base = (authApi.defaults.baseURL ?? "").replace(/\/+$/, "");
53562
+ try {
53563
+ const response = await fetch(`${base}/users/ws-ticket`, {
53564
+ method: "POST",
53565
+ credentials: "include"
53566
+ });
53567
+ if (!response.ok) return null;
53568
+ const data = await response.json();
53569
+ return typeof data.ticket === "string" ? data.ticket : null;
53570
+ } catch {
53571
+ return null;
53572
+ }
53573
+ }
53345
53574
  async function pluginWsUrl(pluginId, path2, options2 = {}) {
53346
53575
  const suffix = path2.startsWith("/") ? path2 : `/${path2}`;
53347
53576
  const route = `/plugin-ws/${pluginId}${suffix}`;
@@ -53353,7 +53582,7 @@ async function pluginWsUrl(pluginId, path2, options2 = {}) {
53353
53582
  remotePath: route
53354
53583
  });
53355
53584
  }
53356
- const token = localStorage.getItem("jwt");
53585
+ const token = await fetchSocketTicket() ?? localStorage.getItem("jwt");
53357
53586
  const protocols2 = websocketAuthProtocols(token);
53358
53587
  const devProxy = !define_import_meta_env_default.VITE_API_HOST && (window.location.port === "3000" || window.location.port === "5173");
53359
53588
  const wsProtocol = window.location.protocol === "https:" ? "wss" : "ws";
@@ -54900,6 +55129,7 @@ export {
54900
55129
  getSecondFactorUI,
54901
55130
  useSecondFactors,
54902
55131
  listSecondFactorUIs,
55132
+ LANGUAGES,
54903
55133
  setPluginLocaleResolver,
54904
55134
  normalizeLanguageCode,
54905
55135
  changeAppLanguage,