@termix-ssh/plugin-sdk 1.0.11 → 1.0.12

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 (117) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/PLUGIN-GUIDE.md +95 -3
  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/capabilities.js +2 -0
  9. package/dist/frontend.d.ts +152 -0
  10. package/dist/frontend.js +7 -0
  11. package/dist/host/PluginsTab-EV4MSGY6.js +2933 -0
  12. package/dist/host/{chunk-RLQBKJRK.js → chunk-AWR6FYDO.js} +8873 -11163
  13. package/dist/host/{chunk-7RRTYD6B.js → chunk-RUPLD6RF.js} +1497 -15
  14. package/dist/host/{chunk-LSWB3ZZV.js → chunk-VEWOYAMZ.js} +6 -1
  15. package/dist/host/chunk-X4QZKO5G.js +3120 -0
  16. package/dist/host/chunk-XKA3DBB2.js +10375 -0
  17. package/dist/host/chunk-YGYBM7SQ.js +58 -0
  18. package/dist/host/core-classes.json +1 -1
  19. package/dist/host/{linked-server-UCW74T2V.js → linked-server-B4NEG4MA.js} +2 -2
  20. package/dist/host/{rbac-api-6UYMFIFV.js → rbac-api-OUO3LUOC.js} +2 -2
  21. package/dist/host/testing-host.js +123 -57
  22. package/dist/host/types/src/types/ui-types.d.ts +2 -1
  23. package/dist/host/types/src/ui/api/audit-log-api.d.ts +46 -0
  24. package/dist/host/types/src/ui/api/host-defaults-api.d.ts +42 -0
  25. package/dist/host/types/src/ui/api/host-tags-api.d.ts +2 -0
  26. package/dist/host/types/src/ui/api/look-api.d.ts +40 -0
  27. package/dist/host/types/src/ui/api/open-tabs-api.d.ts +4 -0
  28. package/dist/host/types/src/ui/api/plugins-api.d.ts +26 -0
  29. package/dist/host/types/src/ui/api/private-endpoints-api.d.ts +6 -0
  30. package/dist/host/types/src/ui/api/tls-api.d.ts +25 -0
  31. package/dist/host/types/src/ui/auth/ElectronLoginForm.d.ts +9 -0
  32. package/dist/host/types/src/ui/components/command.d.ts +78 -0
  33. package/dist/host/types/src/ui/components/folder-style.d.ts +16 -0
  34. package/dist/host/types/src/ui/components/theme-provider.d.ts +2 -1
  35. package/dist/host/types/src/ui/components/version-badge.d.ts +7 -0
  36. package/dist/host/types/src/ui/hooks/use-page-visible-interval.d.ts +10 -0
  37. package/dist/host/types/src/ui/lib/activity-types.d.ts +15 -0
  38. package/dist/host/types/src/ui/lib/app-version.d.ts +2 -0
  39. package/dist/host/types/src/ui/lib/apply-ui-preset.d.ts +19 -0
  40. package/dist/host/types/src/ui/lib/create-id.d.ts +2 -0
  41. package/dist/host/types/src/ui/lib/database-transfer-url.d.ts +8 -0
  42. package/dist/host/types/src/ui/lib/desktop-updates.d.ts +29 -0
  43. package/dist/host/types/src/ui/lib/host-connection-tabs.d.ts +14 -0
  44. package/dist/host/types/src/ui/lib/host-to-ssh-host.d.ts +4 -0
  45. package/dist/host/types/src/ui/lib/issue-url.d.ts +21 -0
  46. package/dist/host/types/src/ui/lib/local-adaptive-preferences.d.ts +9 -0
  47. package/dist/host/types/src/ui/lib/pane-nav-hotkey.d.ts +7 -0
  48. package/dist/host/types/src/ui/lib/plugin-i18n.d.ts +4 -3
  49. package/dist/host/types/src/ui/lib/role-label.d.ts +3 -0
  50. package/dist/host/types/src/ui/look/LookSettings.d.ts +8 -0
  51. package/dist/host/types/src/ui/look/layout-registry.d.ts +34 -0
  52. package/dist/host/types/src/ui/look/look-store.d.ts +29 -0
  53. package/dist/host/types/src/ui/look/resolve-look.d.ts +18 -0
  54. package/dist/host/types/src/ui/look/theme-css.d.ts +7 -0
  55. package/dist/host/types/src/ui/look/theme-registry.d.ts +41 -0
  56. package/dist/host/types/src/ui/look/use-look-theme.d.ts +12 -0
  57. package/dist/host/types/src/ui/manage/manage-requests.d.ts +34 -0
  58. package/dist/host/types/src/ui/plugin-host/loader.d.ts +2 -0
  59. package/dist/host/types/src/ui/plugin-host/scope.d.ts +6 -0
  60. package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +102 -0
  61. package/dist/host/types/src/ui/plugin-host/view-ownership.d.ts +1 -1
  62. package/dist/host/types/src/ui/plugins/PluginConsentPrompt.d.ts +20 -0
  63. package/dist/host/types/src/ui/plugins/PluginDetail.d.ts +7 -0
  64. package/dist/host/types/src/ui/plugins/PluginReleaseNotes.d.ts +14 -0
  65. package/dist/host/types/src/ui/plugins/PluginsTab.d.ts +1 -0
  66. package/dist/host/types/src/ui/plugins/RegistriesSection.d.ts +4 -0
  67. package/dist/host/types/src/ui/plugins/plugin-bits.d.ts +23 -0
  68. package/dist/host/types/src/ui/plugins/plugin-model.d.ts +116 -0
  69. package/dist/host/types/src/ui/plugins/use-plugins-manager.d.ts +75 -0
  70. package/dist/host/types/src/ui/settings/appearance/appearance-controls.d.ts +53 -0
  71. package/dist/host/types/src/ui/settings/sync/LinkServerDialog.d.ts +12 -0
  72. package/dist/host/types/src/ui/settings/sync/ProxySettingsFields.d.ts +15 -0
  73. package/dist/host/types/src/ui/settings/sync/saved-servers.d.ts +3 -0
  74. package/dist/host/types/src/ui/shell/controller/ShellControllerProvider.d.ts +20 -0
  75. package/dist/host/types/src/ui/shell/controller/plugin-shell.d.ts +7 -0
  76. package/dist/host/types/src/ui/shell/controller/shell-store.d.ts +4 -0
  77. package/dist/host/types/src/ui/shell/controller/types.d.ts +156 -0
  78. package/dist/host/types/src/ui/shell/controller/use-hosts.d.ts +10 -0
  79. package/dist/host/types/src/ui/shell/controller/use-regions.d.ts +5 -0
  80. package/dist/host/types/src/ui/shell/controller/use-shell-keybindings.d.ts +12 -0
  81. package/dist/host/types/src/ui/shell/controller/use-shell-lifecycle.d.ts +17 -0
  82. package/dist/host/types/src/ui/shell/controller/use-split.d.ts +21 -0
  83. package/dist/host/types/src/ui/shell/controller/use-tabs.d.ts +70 -0
  84. package/dist/host/types/src/ui/shell/controller/use-workspace-layout.d.ts +4 -0
  85. package/dist/host/types/src/ui/shell/reconnect-tabs.d.ts +6 -0
  86. package/dist/host/types/src/ui/shell/shell-layout.d.ts +46 -0
  87. package/dist/host/types/src/ui/shell/split/EmptyPanePicker.d.ts +32 -0
  88. package/dist/host/types/src/ui/shell/split/SplitDropOverlay.d.ts +9 -0
  89. package/dist/host/types/src/ui/shell/split/SplitLayoutMenu.d.ts +16 -0
  90. package/dist/host/types/src/ui/shell/split/SplitView.d.ts +31 -0
  91. package/dist/host/types/src/ui/shell/split/split-drag.d.ts +58 -0
  92. package/dist/host/types/src/ui/shell/split/split-presets.d.ts +28 -0
  93. package/dist/host/types/src/ui/shell/split/split-tabs.d.ts +95 -0
  94. package/dist/host/types/src/ui/shell/split/split-targets.d.ts +30 -0
  95. package/dist/host/types/src/ui/shell/split/split-tree.d.ts +89 -0
  96. package/dist/host/types/src/ui/shell/stage/TabStage.d.ts +9 -0
  97. package/dist/host/types/src/ui/shell/stage/tab-stage-store.d.ts +24 -0
  98. package/dist/host/types/src/ui/shell/tab-close-guards.d.ts +9 -0
  99. package/dist/host/types/src/ui/shell/tab-handles.d.ts +8 -0
  100. package/dist/host/types/src/ui/shell/tabUtils.d.ts +15 -0
  101. package/dist/host/types/src/ui/sidebar/AuthEnrollmentSections.d.ts +5 -0
  102. package/dist/host/types/src/ui/sidebar/HostManagerData.d.ts +4 -0
  103. package/dist/host/types/src/ui/sidebar/build-host-tree.d.ts +25 -0
  104. package/dist/host/types/src/ui/sidebar/host-export-payload.d.ts +30 -0
  105. package/dist/host/ui.js +6236 -4055
  106. package/dist/host/{use-permissions-GYCBY2AU.js → use-permissions-6VSHHUMB.js} +2 -2
  107. package/dist/manifest.d.ts +41 -1
  108. package/dist/manifest.js +89 -1
  109. package/dist/testing/setup.js +1 -0
  110. package/dist/theme-css.d.ts +11 -0
  111. package/dist/theme-css.js +142 -0
  112. package/dist/vitest-preset.d.ts +18 -0
  113. package/dist/vitest-preset.js +14 -3
  114. package/package.json +1 -1
  115. package/schema/manifest.schema.json +111 -8
  116. package/tsconfig.plugin.json +1 -0
  117. package/dist/host/chunk-YC2MAKSP.js +0 -14
@@ -0,0 +1,42 @@
1
+ import type { HostDefaultsLevel, ResolvedHostDefault } from "../../types/host-defaults";
2
+ export interface HostDefaultsLevelData {
3
+ /** Values set at this level, by "namespace.key". */
4
+ values: Record<string, unknown>;
5
+ /** What each key reads when this level leaves it unset. */
6
+ inherited: Record<string, ResolvedHostDefault>;
7
+ }
8
+ export interface HostDefaultsTarget {
9
+ level: HostDefaultsLevel;
10
+ folderId?: number;
11
+ }
12
+ export interface HostDefaultsChange {
13
+ set: Record<string, unknown>;
14
+ unset: string[];
15
+ }
16
+ export declare function getHostDefaultsLevel(target: HostDefaultsTarget): Promise<HostDefaultsLevelData>;
17
+ export declare function saveHostDefaultsLevel(target: HostDefaultsTarget, change: HostDefaultsChange): Promise<{
18
+ changedHosts?: number;
19
+ jobId?: string;
20
+ }>;
21
+ export declare function previewHostDefaultsLevel(target: HostDefaultsTarget, change: HostDefaultsChange): Promise<{
22
+ changedHosts: number;
23
+ }>;
24
+ export declare function getHostDefaultsJob(id: string): Promise<{
25
+ status: "running" | "done" | "failed";
26
+ changedHosts: number;
27
+ }>;
28
+ /** A folder's id for its defaults, created when it only exists on hosts. */
29
+ export declare function getFolderDefaultsId(name: string): Promise<number>;
30
+ /** What a host, or a new one in a folder or under a parent, resolves to. */
31
+ export declare function resolveHostDefaults(where: {
32
+ hostId?: number;
33
+ folder?: string | null;
34
+ parentHostId?: number | null;
35
+ }, adminTargetUserId?: string): Promise<Record<string, ResolvedHostDefault>>;
36
+ export declare function resetHostToDefaults(hostIds: number[], reset: {
37
+ all?: boolean;
38
+ namespaces?: string[];
39
+ keys?: string[];
40
+ }): Promise<void>;
41
+ /** Waits for a server-wide defaults job. Resolves to the hosts it changed, or null. */
42
+ export declare function waitForDefaultsJob(id: string, intervalMs?: number, maxWaitMs?: number): Promise<number | null>;
@@ -0,0 +1,2 @@
1
+ export declare function getHostTags(): Promise<string[]>;
2
+ export declare function saveHostTags(tags: string[]): Promise<string[]>;
@@ -0,0 +1,40 @@
1
+ /** A layout or theme plugin the server found but could not load. */
2
+ export interface UnavailableLook {
3
+ id: string;
4
+ version: string | null;
5
+ layouts: string[];
6
+ themes: string[];
7
+ error: string;
8
+ }
9
+ /** Everything the browser picks the layout and theme from. */
10
+ export interface LookResponse {
11
+ layoutId: string | null;
12
+ themeId: string | null;
13
+ /** Admin defaults. */
14
+ defaults: {
15
+ layout: string | null;
16
+ theme: string | null;
17
+ };
18
+ /** The default-look plugin's layout and theme. */
19
+ defaultLook: {
20
+ layout: string | null;
21
+ theme: string | null;
22
+ };
23
+ /** TERMIX_SAFE_LAYOUT is set on the server. */
24
+ safeLayout: boolean;
25
+ unavailable: UnavailableLook[];
26
+ }
27
+ export declare function getLook(): Promise<LookResponse>;
28
+ /** The user's own layout and theme; null follows the default. */
29
+ export declare function saveUserLook(look: {
30
+ layoutId?: string | null;
31
+ themeId?: string | null;
32
+ }): Promise<void>;
33
+ /** Admin only. Null clears a default. */
34
+ export declare function saveDefaultLook(defaults: {
35
+ layout?: string | null;
36
+ theme?: string | null;
37
+ }): Promise<{
38
+ layout: string | null;
39
+ theme: string | null;
40
+ }>;
@@ -62,6 +62,10 @@ export interface UserPreferences {
62
62
  compactHostView?: boolean | null;
63
63
  statusColorScheme?: string | null;
64
64
  customKeybindings?: string | null;
65
+ /** Layout this user chose; null follows the admin default. */
66
+ layoutId?: string | null;
67
+ /** Theme this user chose; null follows the admin default. */
68
+ themeId?: string | null;
65
69
  }
66
70
  export declare function parseCustomKeybindings(raw?: string | null): CustomKeybinding[];
67
71
  /**
@@ -56,6 +56,24 @@ export interface PluginViewContribution {
56
56
  titleKey: string;
57
57
  icon?: string;
58
58
  }
59
+ export interface PluginLayoutContribution {
60
+ id: string;
61
+ label: string;
62
+ description?: string;
63
+ defaultTheme?: string;
64
+ default?: boolean;
65
+ }
66
+ export interface PluginThemeContribution {
67
+ id: string;
68
+ label: string;
69
+ mode: "light" | "dark";
70
+ css: string;
71
+ swatch?: {
72
+ background: string;
73
+ panel: string;
74
+ text: string;
75
+ };
76
+ }
59
77
  export interface PluginContributions {
60
78
  tabs?: PluginTabContribution[];
61
79
  panels?: PluginViewContribution[];
@@ -69,6 +87,8 @@ export interface PluginContributions {
69
87
  descriptionKey: string;
70
88
  }[];
71
89
  uiPresets?: PluginUiPresets;
90
+ layouts?: PluginLayoutContribution[];
91
+ themes?: PluginThemeContribution[];
72
92
  }
73
93
  export { isRedactedSecret, type RedactedSecret, } from "@termix-ssh/plugin-sdk/settings";
74
94
  export type PluginSettingsValues = Record<string, unknown>;
@@ -117,6 +137,10 @@ export interface PluginSummary {
117
137
  assetVersion?: string | null;
118
138
  /** "en" plus the xx_YY names of shipped translations. */
119
139
  locales?: string[];
140
+ /** Cache key for the theme CSS files; null without themes. */
141
+ themeVersion?: string | null;
142
+ /** The app is drawn with this plugin by default; it cannot be uninstalled. */
143
+ defaultLook?: boolean;
120
144
  tier?: string;
121
145
  source?: string;
122
146
  /** Capabilities this plugin's manifest declares. Admins only. */
@@ -317,6 +341,8 @@ export declare function setRegistryEnabled(id: string, enabled: boolean): Promis
317
341
  export declare function removeRegistry(id: string): Promise<void>;
318
342
  export declare function updateAllPlugins(): Promise<UpdateAllResult>;
319
343
  export declare function uninstallPlugin(pluginId: string): Promise<void>;
344
+ /** Puts a bundled plugin back to the copy that shipped with this install. */
345
+ export declare function restoreBundledPlugin(pluginId: string): Promise<void>;
320
346
  export declare function previewPluginState(pluginId: string, enabled: boolean): Promise<PluginStateChange>;
321
347
  export declare function setPluginState(pluginId: string, enabled: boolean, consent?: {
322
348
  version: string;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Admin allowlists of private addresses that outbound requests may reach, one
3
+ * per core feature that makes them.
4
+ */
5
+ export declare function getNotificationPrivateEndpoints(): Promise<string[]>;
6
+ export declare function setNotificationPrivateEndpoints(hosts: string[]): Promise<string[]>;
@@ -0,0 +1,25 @@
1
+ export type TlsCertificateInfo = {
2
+ subject: string;
3
+ issuer: string;
4
+ names: string[];
5
+ notBefore: string;
6
+ notAfter: string;
7
+ selfSigned: boolean;
8
+ fingerprint: string;
9
+ };
10
+ export type TlsStatus = {
11
+ enabled: boolean;
12
+ certificate: TlsCertificateInfo | null;
13
+ renewal: {
14
+ pluginId: string;
15
+ pluginName: string;
16
+ } | null;
17
+ };
18
+ export declare function getTlsStatus(): Promise<TlsStatus>;
19
+ export declare function uploadTlsCertificate(payload: {
20
+ certificate: string;
21
+ privateKey: string;
22
+ }): Promise<TlsStatus & {
23
+ success: boolean;
24
+ reloadMessage?: string;
25
+ }>;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface ElectronLoginFormProps {
3
+ serverUrl: string;
4
+ onAuthSuccess: (token: string | null) => void | Promise<void>;
5
+ onChangeServer: () => void;
6
+ targetPurpose?: "local" | "link";
7
+ }
8
+ export declare function ElectronLoginForm({ serverUrl, onAuthSuccess, onChangeServer, targetPurpose, }: ElectronLoginFormProps): React.JSX.Element;
9
+ export {};
@@ -0,0 +1,78 @@
1
+ import * as React from "react";
2
+ declare const Command: React.ForwardRefExoticComponent<Omit<{
3
+ children?: React.ReactNode;
4
+ } & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
5
+ ref?: React.Ref<HTMLDivElement>;
6
+ } & {
7
+ asChild?: boolean;
8
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
9
+ label?: string;
10
+ shouldFilter?: boolean;
11
+ filter?: (value: string, search: string, keywords?: string[]) => number;
12
+ defaultValue?: string;
13
+ value?: string;
14
+ onValueChange?: (value: string) => void;
15
+ loop?: boolean;
16
+ disablePointerSelection?: boolean;
17
+ vimBindings?: boolean;
18
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
19
+ declare const CommandInput: React.ForwardRefExoticComponent<Omit<Omit<Pick<Pick<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof React.InputHTMLAttributes<HTMLInputElement>> & {
20
+ ref?: React.Ref<HTMLInputElement>;
21
+ } & {
22
+ asChild?: boolean;
23
+ }, "key" | "asChild" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "onChange" | "type" | "value"> & {
24
+ value?: string;
25
+ onValueChange?: (search: string) => void;
26
+ } & React.RefAttributes<HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
27
+ declare const CommandList: React.ForwardRefExoticComponent<Omit<{
28
+ children?: React.ReactNode;
29
+ } & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
30
+ ref?: React.Ref<HTMLDivElement>;
31
+ } & {
32
+ asChild?: boolean;
33
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
34
+ label?: string;
35
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
36
+ declare const CommandGroup: React.ForwardRefExoticComponent<Omit<{
37
+ children?: React.ReactNode;
38
+ } & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
39
+ ref?: React.Ref<HTMLDivElement>;
40
+ } & {
41
+ asChild?: boolean;
42
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "heading" | "value"> & {
43
+ heading?: React.ReactNode;
44
+ value?: string;
45
+ forceMount?: boolean;
46
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
47
+ declare const CommandSeparator: React.ForwardRefExoticComponent<Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
48
+ ref?: React.Ref<HTMLDivElement>;
49
+ } & {
50
+ asChild?: boolean;
51
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
52
+ alwaysRender?: boolean;
53
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
54
+ declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
55
+ children?: React.ReactNode;
56
+ } & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
57
+ ref?: React.Ref<HTMLDivElement>;
58
+ } & {
59
+ asChild?: boolean;
60
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "onSelect" | "disabled" | "value"> & {
61
+ disabled?: boolean;
62
+ onSelect?: (value: string) => void;
63
+ value?: string;
64
+ keywords?: string[];
65
+ forceMount?: boolean;
66
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
67
+ declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
68
+ children?: React.ReactNode;
69
+ } & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
70
+ ref?: React.Ref<HTMLDivElement>;
71
+ } & {
72
+ asChild?: boolean;
73
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
74
+ declare const CommandShortcut: {
75
+ ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>): React.JSX.Element;
76
+ displayName: string;
77
+ };
78
+ export { Command, CommandInput, CommandList, CommandGroup, CommandItem, CommandSeparator, CommandEmpty, CommandShortcut, };
@@ -0,0 +1,16 @@
1
+ export declare const DEFAULT_FOLDER_ICON = "folder";
2
+ export declare const DEFAULT_FOLDER_COLOR = "#f59145";
3
+ export declare function FolderIconEl({ icon, className, style, }: {
4
+ icon?: string | null;
5
+ className?: string;
6
+ style?: React.CSSProperties;
7
+ }): import("react").JSX.Element;
8
+ export declare function HexColorPicker({ value, onChange, }: {
9
+ value: string;
10
+ onChange: (hex: string) => void;
11
+ }): import("react").JSX.Element;
12
+ export declare function IconPicker({ value, color, onChange, }: {
13
+ value: string;
14
+ color?: string;
15
+ onChange: (icon: string) => void;
16
+ }): import("react").JSX.Element;
@@ -6,7 +6,8 @@ type ThemeProviderProps = {
6
6
  };
7
7
  type ThemeProviderState = {
8
8
  theme: ThemeId;
9
- setTheme: (theme: ThemeId) => void;
9
+ /** Pass persist false to show a theme without keeping it in this browser. */
10
+ setTheme: (theme: ThemeId, persist?: boolean) => void;
10
11
  setThemePreview: (theme: ThemeId | null) => void;
11
12
  };
12
13
  export declare function ThemeProvider({ children, defaultTheme, storageKey, ...props }: ThemeProviderProps): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ interface VersionBadgeProps {
2
+ status: "up_to_date" | "requires_update" | "beta" | "unknown";
3
+ releaseUrl?: string;
4
+ className?: string;
5
+ }
6
+ export declare function VersionBadge({ status, releaseUrl, className, }: VersionBadgeProps): import("react").JSX.Element;
7
+ export {};
@@ -0,0 +1,10 @@
1
+ type Options = {
2
+ /** Run callback once when the effect mounts (if visible). Default true. */
3
+ runOnMount?: boolean;
4
+ };
5
+ /**
6
+ * Runs `callback` on `intervalMs` while the page is visible.
7
+ * Pauses when the tab is backgrounded; fires once on resume.
8
+ */
9
+ export declare function usePageVisibleInterval(callback: () => void, intervalMs: number, enabled?: boolean, options?: Options): void;
10
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { ComponentType } from "react";
2
+ export interface ActivityTarget {
3
+ icon: ComponentType<{
4
+ className?: string;
5
+ }> | undefined;
6
+ /** Tab type the entry reopens. */
7
+ tab: string;
8
+ labelKey: string | undefined;
9
+ }
10
+ /**
11
+ * What a recent-activity entry opens and how it is labelled. Plugin tabs
12
+ * claim their activity types through the registry, so an entry whose plugin
13
+ * is gone simply has no target.
14
+ */
15
+ export declare function activityTarget(type: string): ActivityTarget | undefined;
@@ -0,0 +1,2 @@
1
+ /** The version of this build, empty in a dev build. */
2
+ export declare const APP_VERSION: string | undefined;
@@ -0,0 +1,19 @@
1
+ import { type UiPreset, type UiRailPreferences } from "../../types/ui-preferences";
2
+ import { type RailItemDef } from "../sidebar/rail-items";
3
+ export declare function buildDashboardSlots(cardIds: string[]): {
4
+ key: string;
5
+ id: string;
6
+ panel: "main" | "side";
7
+ order: number;
8
+ height: number;
9
+ }[];
10
+ /**
11
+ * The rail views a preset hides: its own list, plus every plugin item that
12
+ * does not ask to stay when the preset hides plugin items.
13
+ */
14
+ export declare function presetHiddenRailTabs(rail: UiRailPreferences, pluginItems: Pick<RailItemDef, "id" | "simplePreset" | "hideable">[]): string[];
15
+ /**
16
+ * Writes a preset's values into the stores that own them. Safe to call when
17
+ * nothing changed; every write is idempotent.
18
+ */
19
+ export declare function applyPresetSideEffects(preset: Exclude<UiPreset, "custom">): Promise<void>;
@@ -0,0 +1,2 @@
1
+ /** A random id, with a fallback for insecure contexts that lack randomUUID. */
2
+ export declare function createId(): string;
@@ -0,0 +1,8 @@
1
+ type BrowserLocation = Pick<Location, "protocol" | "host" | "hostname" | "port">;
2
+ interface DatabaseTransferUrlOptions {
3
+ electron: boolean;
4
+ configuredServerUrl?: string | null;
5
+ location: BrowserLocation;
6
+ }
7
+ export declare function getDatabaseTransferUrl(operation: "export" | "import", { electron, configuredServerUrl, location }: DatabaseTransferUrlOptions): string;
8
+ export {};
@@ -0,0 +1,29 @@
1
+ export type DesktopUpdateMode = "automatic" | "prompt" | "never";
2
+ export type DesktopInstallKind = "auto" | "manual" | "store" | "disabled";
3
+ export type DesktopUpdateStatus = "idle" | "checking" | "available" | "downloading" | "downloaded" | "up-to-date" | "error";
4
+ export interface DesktopUpdateState {
5
+ kind: DesktopInstallKind;
6
+ mode: DesktopUpdateMode;
7
+ currentVersion: string;
8
+ status: DesktopUpdateStatus;
9
+ version: string | null;
10
+ releaseUrl: string | null;
11
+ progress: number | null;
12
+ error: string | null;
13
+ }
14
+ interface DesktopUpdatesBridge {
15
+ getState: () => Promise<DesktopUpdateState | null>;
16
+ check: () => Promise<DesktopUpdateState | null>;
17
+ download: () => Promise<DesktopUpdateState | null>;
18
+ install: () => Promise<boolean>;
19
+ setMode: (mode: DesktopUpdateMode) => Promise<DesktopUpdateState | null>;
20
+ onState: (callback: (state: DesktopUpdateState) => void) => () => void;
21
+ }
22
+ /** The main process updater, or null in the browser and on older builds. */
23
+ export declare function desktopUpdates(): DesktopUpdatesBridge | null;
24
+ /** Whether this install has an updater the user can configure. */
25
+ export declare function canConfigureUpdates(state: DesktopUpdateState | null): state is DesktopUpdateState;
26
+ /** Which toast, if any, this state calls for. */
27
+ export declare function updateToastFor(state: DesktopUpdateState | null): "prompt" | "manual" | "ready" | null;
28
+ export declare function useDesktopUpdate(): DesktopUpdateState | null;
29
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { Host, TabType } from "../../types/ui-types";
2
+ /**
3
+ * Which tab a click on a host opens. The ways to connect (the SSH terminal,
4
+ * remote desktop) are host actions that plugins register, so the answer is the
5
+ * highest-priority connect action the host allows, or null when no running
6
+ * plugin can connect to it.
7
+ */
8
+ export declare function getDefaultConnectionTab(host: Host): TabType | null;
9
+ /**
10
+ * The preferred tab if the host allows it. A connect tab type the host has
11
+ * switched off falls back to the host's default; any other type is taken as
12
+ * asked.
13
+ */
14
+ export declare function resolveHostTabType(host: Host, preferredType?: TabType): TabType | null;
@@ -0,0 +1,4 @@
1
+ import type { Host } from "../../types/ui-types";
2
+ import type { SSHHost } from "../../types";
3
+ /** The shell's Host in the SSHHost shape the connection surfaces take. */
4
+ export declare function hostToSSHHost(h: Host): SSHHost;
@@ -0,0 +1,21 @@
1
+ export declare const CORE_REPO_URL = "https://github.com/Termix-SSH/Termix";
2
+ /** A GitHub repo URL without .git or a trailing slash, or null if it is not one. */
3
+ export declare function normalizeGitHubRepo(repository?: string | null): string | null;
4
+ /**
5
+ * A new issue from one of the repo's issue forms, with fields prefilled by
6
+ * their form ids. Logs get cut first when the URL would be too long.
7
+ */
8
+ export declare function buildIssueUrl(repo: string, options: {
9
+ template: string;
10
+ title?: string;
11
+ fields?: Record<string, string | null | undefined>;
12
+ }): string;
13
+ /** One line on where Termix is running, for the environment field. */
14
+ export declare function describeEnvironment(userAgent?: string, desktop?: boolean): string;
15
+ /** A bug report on the Termix core repo. */
16
+ export declare function reportCoreIssueUrl(termixVersion?: string): string;
17
+ /** Beta feedback on the core repo, listing every plugin running a beta. */
18
+ export declare function reportBetaFeedbackUrl(termixVersion?: string, betaPlugins?: Array<{
19
+ id: string;
20
+ version: string;
21
+ }>): string;
@@ -0,0 +1,9 @@
1
+ import type { TabType } from "../../types/ui-types";
2
+ export declare const LOCAL_ADAPTIVE_PREFERENCES_KEY = "termix.local.adaptive-engine.v1";
3
+ /** Records an abstract action locally. Callers must not use raw paths or input. */
4
+ export declare function recordLocalPreference(scope: string, action: string, now?: number): void;
5
+ /** Returns a learned action only after enough consistent local evidence. */
6
+ export declare function getLocalPreference<T extends string>(scope: string, candidates: readonly T[], fallback: T, now?: number): T;
7
+ export declare function clearLocalAdaptivePreferences(): void;
8
+ export declare function recordHostActionPreference(hostId: string, action: TabType): void;
9
+ export declare function getPreferredHostAction(hostId: string, candidates: readonly TabType[], fallback: TabType): TabType;
@@ -0,0 +1,7 @@
1
+ export type PaneNavDirection = "left" | "right" | "up" | "down";
2
+ /**
3
+ * The split pane to move to for this key, if any. Cmd+Option+Arrow on macOS,
4
+ * where Option+Arrow moves the shell cursor by word, Alt+Arrow elsewhere.
5
+ */
6
+ export declare function getPaneNavDirection(e: KeyboardEvent): PaneNavDirection | null;
7
+ export declare function paneNavHotkeyLabel(): string;
@@ -1,4 +1,5 @@
1
- import type { TFunction } from "i18next";
1
+ /** The part of a translate function these helpers use. */
2
+ export type Translator = (key: string, options?: Record<string, unknown>) => string;
2
3
  /**
3
4
  * Where a plugin's i18n keys resolve from.
4
5
  *
@@ -15,12 +16,12 @@ export declare function pluginKey(pluginId: string, key: string | undefined): st
15
16
  * else the manifest's. A plugin whose strings are not loaded, like one only
16
17
  * listed in a registry, shows the manifest name.
17
18
  */
18
- export declare function pluginName(t: TFunction, plugin: {
19
+ export declare function pluginName(t: Translator, plugin: {
19
20
  id: string;
20
21
  name: string;
21
22
  }): string;
22
23
  /** Same as pluginName, for "plugin.description". */
23
- export declare function pluginDescription(t: TFunction, plugin: {
24
+ export declare function pluginDescription(t: Translator, plugin: {
24
25
  id: string;
25
26
  description?: string | null;
26
27
  }): string;
@@ -0,0 +1,3 @@
1
+ import type { Translator } from "./plugin-i18n";
2
+ /** System roles store an i18n key as their display name. */
3
+ export declare function roleLabel<T extends string | null | undefined>(t: Translator, displayName: T): T | string;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The layout picker, plus the default layout and theme for everyone when an
3
+ * admin is looking. Lists what the layout and theme registries hold, so
4
+ * plugin layouts and themes show up as soon as they are installed.
5
+ */
6
+ export declare function LookSettings({ isAdmin }: {
7
+ isAdmin: boolean;
8
+ }): import("react").JSX.Element;
@@ -0,0 +1,34 @@
1
+ import { type ComponentType } from "react";
2
+ import type { TFunction } from "i18next";
3
+ /** A layout someone can choose, known from a manifest before its code loads. */
4
+ export interface LayoutDescriptor {
5
+ id: string;
6
+ /** i18n key in the plugin namespace, or plain text. */
7
+ label: string;
8
+ description?: string;
9
+ defaultTheme?: string;
10
+ /** Set for a plugin layout. */
11
+ pluginId?: string;
12
+ }
13
+ /** A layout whose code is running, from app.registerLayout. */
14
+ export interface RegisteredLayout {
15
+ id: string;
16
+ pluginId?: string;
17
+ component: ComponentType;
18
+ /** Shown on phones and narrow windows. Never in the desktop app. */
19
+ mobileComponent?: ComponentType;
20
+ defaultTheme?: string;
21
+ }
22
+ export declare const registerLayout: (item: RegisteredLayout) => () => void;
23
+ export declare const getRegisteredLayout: (id: string) => RegisteredLayout;
24
+ export declare const useRegisteredLayouts: () => RegisteredLayout[];
25
+ export declare const resetRegisteredLayouts: () => void;
26
+ /** Every layout that can be chosen, from the installed plugins. */
27
+ export declare function listLayouts(): LayoutDescriptor[];
28
+ export declare function getLayoutDescriptor(id: string): LayoutDescriptor | undefined;
29
+ /** Replaces the plugin layouts at once, from the plugin list. */
30
+ export declare function setPluginLayouts(layouts: LayoutDescriptor[]): void;
31
+ export declare function useLayouts(): LayoutDescriptor[];
32
+ export declare function layoutLabel(layout: LayoutDescriptor, t: TFunction): string;
33
+ /** Test seam. */
34
+ export declare function resetPluginLayouts(): void;
@@ -0,0 +1,29 @@
1
+ import { type LookResponse } from "../api/look-api";
2
+ interface LookState {
3
+ /** The server answered, or failed to; the look is decided either way. */
4
+ loaded: boolean;
5
+ response: LookResponse | null;
6
+ }
7
+ /** Fetches the look once per session. Never rejects: no answer means defaults. */
8
+ export declare function loadLook(): Promise<LookResponse | null>;
9
+ /** Fetches again, e.g. after an admin changed the defaults. */
10
+ export declare function reloadLook(): Promise<LookResponse | null>;
11
+ /** On logout: the next user has their own look. */
12
+ export declare function resetLook(): void;
13
+ export declare function getLookState(): LookState;
14
+ export declare function subscribeLook(listener: () => void): () => void;
15
+ export declare function useLookState(): LookState;
16
+ /** The layout to show now. Remembered so a failed fetch next time still knows. */
17
+ export declare function chosenLayoutId(): string;
18
+ /** The URL or the server asks for the repair view. */
19
+ export declare function safeLayoutRequested(): boolean;
20
+ /** The user's own layout; null goes back to the default. */
21
+ export declare function chooseLayout(layoutId: string | null): Promise<void>;
22
+ /** The user's own theme; null goes back to the default. */
23
+ export declare function chooseThemeForAccount(themeId: string | null): Promise<void>;
24
+ /** Admin only: what everyone sees until they choose their own. */
25
+ export declare function chooseDefaultLook(defaults: {
26
+ layout?: string | null;
27
+ theme?: string | null;
28
+ }): Promise<void>;
29
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { LookResponse } from "../api/look-api";
2
+ /** The theme a fresh install starts in when nothing else says otherwise. */
3
+ export declare const FALLBACK_THEME = "dark";
4
+ /**
5
+ * The layout to show: the user's choice, else the admin default, else the
6
+ * default look. Empty when none of them names one, which the repair view
7
+ * answers. Without an answer from the server the last layout this browser
8
+ * showed stands in.
9
+ */
10
+ export declare function resolveLayoutId(look: LookResponse | null, lastShown?: string | null): string;
11
+ /**
12
+ * The theme to show: the user's choice, else the one this browser kept
13
+ * (today's per-device setting, so existing users see no change), else the
14
+ * admin default, else the layout's own, else the default look's.
15
+ */
16
+ export declare function resolveThemeId(look: LookResponse | null, localTheme: string | null, layoutDefaultTheme?: string): string;
17
+ /** ?safe-layout=1 in the address bar opens the repair view. */
18
+ export declare function safeLayoutInUrl(search: string): boolean;
@@ -0,0 +1,7 @@
1
+ import { type ThemeDef } from "./theme-registry";
2
+ /**
3
+ * Loads the one plugin theme stylesheet the shown theme needs, and only that
4
+ * one. Built-in themes need none. A theme whose plugin has not loaded yet
5
+ * keeps the stylesheet it had last time.
6
+ */
7
+ export declare function applyThemeCss(id: string, theme: ThemeDef | undefined): void;