@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
@@ -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;
@@ -0,0 +1,41 @@
1
+ import type { TFunction } from "i18next";
2
+ /** Follows the OS between the light and dark theme. Not a real theme. */
3
+ export declare const SYSTEM_THEME = "system";
4
+ export interface ThemeSwatch {
5
+ background: string;
6
+ panel: string;
7
+ text: string;
8
+ }
9
+ export interface ThemeDef {
10
+ /** Also the class put on <html> while the theme is active. */
11
+ id: string;
12
+ /** i18n key: core's for built-ins, the plugin namespace's for plugins. */
13
+ label: string;
14
+ mode: "light" | "dark";
15
+ swatch: ThemeSwatch;
16
+ /** Set for a plugin theme. */
17
+ pluginId?: string;
18
+ /** Where a plugin theme's CSS is served. Built-ins live in index.css. */
19
+ cssHref?: string;
20
+ }
21
+ /**
22
+ * The two themes core keeps as a fallback, with their tokens in index.css.
23
+ * The rest come from theme plugins. A plugin theme with the same id takes
24
+ * the built-in's place while it is installed.
25
+ */
26
+ export declare const BUILTIN_THEMES: readonly ThemeDef[];
27
+ /** Built-ins in their order, a plugin theme in a built-in's place, then the rest as declared. */
28
+ export declare function listThemes(): ThemeDef[];
29
+ export declare function getTheme(id: string): ThemeDef | undefined;
30
+ /** Replaces every plugin theme at once, from the plugin list. */
31
+ export declare function setPluginThemes(themes: ThemeDef[]): void;
32
+ export declare function subscribeThemes(listener: () => void): () => void;
33
+ export declare function useThemes(): ThemeDef[];
34
+ /** The light or dark mode a theme id stands for, following the OS for system. */
35
+ export declare function themeMode(id: string): "light" | "dark";
36
+ /** The theme to show for a saved id: itself, or System when it is gone. */
37
+ export declare function effectiveThemeId(id: string): string;
38
+ export declare function themeLabel(theme: ThemeDef, t: TFunction): string;
39
+ export declare function arePluginThemesKnown(): boolean;
40
+ /** On logout, and a test seam. */
41
+ export declare function resetPluginThemes(): void;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shows the theme the look settles on once it is known. A theme someone
3
+ * picked themselves is kept in this browser too; a default is only shown,
4
+ * so a later default change still reaches them.
5
+ */
6
+ export declare function useLookTheme(layoutId: string): void;
7
+ /**
8
+ * Picks a theme for this user: shown now and kept in this browser. Unless
9
+ * they keep settings on this device only, it is saved to their account too,
10
+ * which is what other devices follow.
11
+ */
12
+ export declare function useChooseTheme(): (themeId: string) => void;
@@ -103,7 +103,7 @@ export declare const appReadyPromise: Promise<void>;
103
103
  */
104
104
  export declare function isLoginRequestUrl(url: string | undefined): boolean;
105
105
  export declare function handleApiError(error: unknown, operation: string): never;
106
- export { getSSHHosts, createSSHHost, updateSSHHost, bulkImportSSHHosts, importSSHConfigHosts, bulkUpdateSSHHosts, reorderSSHHosts, deleteSSHHost, getSSHHostById, exportSSHHostWithCredentials, exportAllSSHHosts, testProxyConnection, } from "./api/ssh-host-management-api";
106
+ export { getSSHHosts, createSSHHost, updateSSHHost, bulkUpdateSSHHosts, reorderSSHHosts, deleteSSHHost, getSSHHostById, testProxyConnection, } from "./api/ssh-host-management-api";
107
107
  export { getAllServerStatuses, getServerStatusById, refreshServerPolling, getStatusCheckSettings, updateStatusCheckSettings, } from "./api/host-status-api";
108
108
  export { getHostSidebarPreferences, saveHostSidebarPreferences, } from "./api/host-sidebar-preferences-api";
109
109
  export { getCredentialSidebarPreferences, saveCredentialSidebarPreferences, } from "./api/credential-sidebar-preferences-api";
@@ -165,7 +165,7 @@ export declare function changePassword(oldPassword: string, newPassword: string)
165
165
  export { getUserList, getSessions, revokeSession, revokeAllUserSessions, createApiKey, getApiKeys, deleteApiKey, makeUserAdmin, removeAdminStatus, deleteUser, deleteAccount, updateRegistrationAllowed, getExternalAutoProvision, updateExternalAutoProvision, getSecondFactorAfterExternalLogin, updateSecondFactorAfterExternalLogin, updatePasswordLoginAllowed, getPasswordResetAllowed, updatePasswordResetAllowed, adminResetUserPassword, adminExportUserData, type ApiKey, type CreatedApiKey, } from "./api/user-management-api";
166
166
  export { adminGetUserHosts, adminCreateUserHost, adminUpdateUserHost, adminDeleteUserHost, adminGetHostPassword, adminGetUserCredentials, adminGetUserCredentialDetails, adminCreateUserCredential, adminUpdateUserCredential, adminDeleteUserCredential, } from "./api/admin-user-data-api";
167
167
  export { getReleasesRSS, getVersionInfo, releaseUrlFrom, getDatabaseHealth, } from "./api/system-status-api";
168
- export { getCredentials, getCredentialDetails, createCredential, updateCredential, duplicateCredential, deleteCredential, getCredentialHosts, getCredentialFolders, getSSHHostWithCredentials, getHostPassword, applyCredentialToHost, removeCredentialFromHost, migrateHostToCredential, getFoldersWithStats, renameFolder, getSSHFolders, updateFolderMetadata, reorderFolders, deleteAllHostsInFolder, renameCredentialFolder, reorderCredentials, detectKeyType, detectPublicKeyType, validateKeyPair, generatePublicKeyFromPrivate, generateKeyPair, deployCredentialToHost, } from "./api/credentials-api";
168
+ export { getCredentials, getCredentialDetails, createCredential, updateCredential, duplicateCredential, deleteCredential, getCredentialHosts, getCredentialFolders, getSSHHostWithCredentials, getHostPassword, applyCredentialToHost, removeCredentialFromHost, migrateHostToCredential, getFoldersWithStats, renameFolder, getSSHFolders, updateFolderMetadata, reorderFolders, deleteAllHostsInFolder, renameCredentialFolder, reorderCredentials, } from "./api/credentials-api";
169
169
  export type { UptimeInfo, RecentActivityItem } from "./api/dashboard-api";
170
170
  export { getUptime, getRecentActivity, logActivity, resetRecentActivity, } from "./api/dashboard-api";
171
171
  export { linkExternalToPasswordAccount, unlinkExternalFromPasswordAccount, } from "./api/external-account-api";
@@ -0,0 +1,34 @@
1
+ import type { HostDraft } from "@termix-ssh/plugin-sdk/frontend";
2
+ import type { HostDefaultsLevel } from "../../types/host-defaults";
3
+ export type ManageMode = "hosts" | "credentials" | "defaults";
4
+ /** What to open in the Manage tab. */
5
+ export type ManageRequest = {
6
+ kind: "host";
7
+ hostId: string | null;
8
+ draft?: HostDraft;
9
+ } | {
10
+ kind: "credential";
11
+ credentialId: string | null;
12
+ } | {
13
+ kind: "defaults";
14
+ level: HostDefaultsLevel;
15
+ folderName?: string;
16
+ } | {
17
+ kind: "browse";
18
+ mode: ManageMode;
19
+ };
20
+ export declare const MANAGE_REQUEST_EVENT = "manage:request";
21
+ /**
22
+ * Parks a request for the Manage tab and pokes it. The shell opens the tab on
23
+ * the same event, and the tab claims the parked request once it mounts.
24
+ */
25
+ export declare function requestManage(request: ManageRequest): void;
26
+ /** Takes the parked request, leaving none behind. */
27
+ export declare function takePendingManageRequest(): ManageRequest | null;
28
+ /**
29
+ * The window events older callers fire (the dashboard, folder menus, the
30
+ * palette), turned into a request. Null for anything else.
31
+ */
32
+ export declare function requestFromLegacyEvent(name: string, detail?: unknown): ManageRequest | null;
33
+ /** Test seam. */
34
+ export declare function resetManageRequests(): void;
@@ -36,12 +36,14 @@ export interface OnboardingStepDef {
36
36
  forcePending?: (ctx: OnboardingCtx) => boolean;
37
37
  /** Skip stays hidden until this step has been confirmed. */
38
38
  required?: boolean;
39
+ /** Older step keys this one took over; seeing one counts as seeing this. */
40
+ replaces?: string[];
39
41
  }
40
42
  /** Where each section of plugin steps sits among the core steps. */
41
43
  export declare const SECTION_POSITION: Record<OnboardingSection, number>;
42
44
  export declare const onboardingSteps: import("../lib/registry").Registry<OnboardingStepDef>;
43
45
  /** Plugin steps sort inside their section by order, then key. */
44
- export declare function sectionPosition(section: OnboardingSection | undefined, order?: number): number;
46
+ export declare function sectionPosition(section: OnboardingSection | undefined, order?: number, position?: number): number;
45
47
  export declare function sortSteps(steps: OnboardingStepDef[]): OnboardingStepDef[];
46
48
  /** Steps still on the deprecated onboarding.steps slot, read as version 1. */
47
49
  export declare function legacyStepDefs(contributions: SlotContribution[]): OnboardingStepDef[];
@@ -23,6 +23,8 @@ export declare function orderForActivation(summaries: PluginSummary[]): {
23
23
  * to call as often as needed; calls run one after another.
24
24
  */
25
25
  export declare function syncPlugins(summaries?: PluginSummary[]): Promise<void>;
26
+ /** Tries a plugin's frontend again even though this bundle failed before. */
27
+ export declare function retryPluginFrontend(pluginId: string): Promise<void>;
26
28
  /**
27
29
  * The `?view=` names enabled guest plugins serve to anonymous pages, so the
28
30
  * entry point can tell a guest link from a signed-in full-screen view
@@ -7,6 +7,12 @@ export declare function usePluginScope(): string | null;
7
7
  * without each call site having to remember.
8
8
  */
9
9
  export declare function withPluginScope<P extends object>(pluginId: string, Inner: ComponentType<P>): ComponentType<P>;
10
+ /**
11
+ * The plugin id for the hooks without the error boundary, for a component
12
+ * whose caller handles a crash itself (a layout, which the repair view takes
13
+ * over from).
14
+ */
15
+ export declare function withPluginContext<P extends object>(pluginId: string, Inner: ComponentType<P>): ComponentType<P>;
10
16
  /**
11
17
  * A plugin icon the shell renders inline (rail, tab strip, host row). Small
12
18
  * enough that a broken one should just disappear, not take the row with it.
@@ -47,6 +47,8 @@ export { BrowserSignInDialog } from "../ssh/dialogs/BrowserSignInDialog";
47
47
  export { FOLDER_COLORS } from "../lib/theme";
48
48
  export { useTabs, useTabsSafe } from "../shell/TabContext";
49
49
  export { ActionSlot, ComponentSlot } from "../shell/ActionSlot";
50
+ export { TabStage } from "../shell/stage/TabStage";
51
+ export { ShellConfirmCapture } from "../shell/controller/ShellControllerProvider";
50
52
  export { HostFeatureFields, type HostFeatureFieldsProps, } from "../settings/HostPluginSections";
51
53
  export { HostDefaultBadge, DefaultsOnly as HostDefaultField, useIsDefaultsEditor, } from "../lib/host-defaults-context";
52
54
  export { PluginComponent } from "./component-registry";
@@ -99,3 +101,102 @@ export { InlineView, PanePrompt, SurfaceScope, useConfirm, useSurfaceKind, type
99
101
  export { PROMPT_BUTTON, PROMPT_DESTRUCTIVE_BUTTON, PROMPT_PRIMARY_BUTTON, } from "../components/surface/prompt-styles";
100
102
  export { ConnectionGate, useConnectionGate, type ConnectionGateController, type ConnectionGateProps, } from "../components/connection/ConnectionGate";
101
103
  export { type ConnectionUnavailable } from "../components/connection/ConnectionScreen";
104
+ export { APP_VERSION } from "../lib/app-version";
105
+ export { Command as CommandPrimitive } from "cmdk";
106
+ export { type AuthOverrideProtocol, SSH_AUTH_PROTOCOL, } from "../../types/auth-protocols";
107
+ export { CREDENTIAL_ROW_FIELD_KEYS, type CredentialDensity, type CredentialRowFields, type CredentialSidebarFilterState, type CredentialSidebarPreferences, type CredentialSortKey, type CredentialTrayTrigger, defaultCredentialRowFields, defaultCredentialSidebarPreferences, sanitizeCredentialSidebarPreferences, } from "../../types/credential-sidebar-preferences";
108
+ export { CORE_HOST_DEFAULTS, CORE_NAMESPACE, type DefaultOverrides, defaultValuesEqual, findCoreHostDefault, type HostDefaultsLevel, type ResolvedHostDefault, splitDefaultKey, } from "../../types/host-defaults";
109
+ export { defaultHostRowFields, defaultHostSidebarPreferences, type HostClickBehavior, type HostDensity, type HostGroupKey, type HostRowFields, type HostSidebarFilterState, type HostSidebarPreferences, type HostTrayTrigger, sanitizeHostSidebarPreferences, type SortKey, } from "../../types/host-sidebar-preferences";
110
+ export type { HostData, HostProtocolAuthInput, ProxyNode, SSHHost, SSHHostData, } from "../../types";
111
+ export { PRESETS, UI_AREA_KEYS, type UiAreaKey, type UiPreset, } from "../../types/ui-preferences";
112
+ export type { AdminSection, Credential, DashboardCardId, FontSizeId, Host, HostFolder, SharePermissionLevel, Tab, TabType, ThemeId, ToolsTab, UiFontId, } from "../../types/ui-types";
113
+ export { type AuditLog, type AuditLogFilters, getAuditLogActions, getAuditLogs, } from "../api/audit-log-api";
114
+ export { getUserSecondFactors, resetUserSecondFactors, type UserSecondFactorSummary, } from "../api/auth-methods-api";
115
+ export { getCredentials } from "../api/credentials-api";
116
+ export { getFolderDefaultsId, getHostDefaultsLevel, type HostDefaultsChange, type HostDefaultsTarget, previewHostDefaultsLevel, resetHostToDefaults, resolveHostDefaults, saveHostDefaultsLevel, waitForDefaultsJob, } from "../api/host-defaults-api";
117
+ export { getHostTags, saveHostTags } from "../api/host-tags-api";
118
+ export { getSessionTimeoutMinutes, getUserPreferences, parseCustomKeybindings, saveUserPreferences, } from "../api/open-tabs-api";
119
+ export { getDeveloperMode, getPluginAdminSettings, getPluginHostSettings, getPlugins, getPluginUserSettings, type PluginSettingsErrors, type PluginSettingsField, PluginSettingsValidationError, type PluginSummary, setAllPluginChannels, setDeveloperMode, setPluginOptions, updatePluginAdminSettings, updatePluginHostSettings, updatePluginUserSettings, } from "../api/plugins-api";
120
+ export { getNotificationPrivateEndpoints, setNotificationPrivateEndpoints, } from "../api/private-endpoints-api";
121
+ export { type CredentialPermissionLevel, type FolderAccessRule, getCredentialAccess, getFolderAccess, getRoles, revokeCredentialAccess, revokeFolderAccess, shareCredential, type ShareTarget, } from "../api/rbac-api";
122
+ export { type BrandingSettings, getBranding } from "../api/settings-api";
123
+ export { getSyncConflicts, getSyncErrors, retrySyncErrors, settleSyncConflict, type SyncBasicAuth, type SyncConflictItem, type SyncEntityInfo, type SyncErrorItem, syncNow, type SyncProxyHeader, type SyncStatus, unlinkServer, updateSyncSettings, } from "../api/sync-api";
124
+ export { getChannelReleases, getUpdateChannel, type ReleaseInfo, setUpdateChannel, type UpdateChannelState, } from "../api/system-status-api";
125
+ export { getTlsStatus, type TlsStatus, uploadTlsCertificate, } from "../api/tls-api";
126
+ export { Command, CommandEmpty, CommandGroup, CommandItem, CommandList, } from "../components/command";
127
+ export { usePluginDocsUrl } from "../components/docs-link";
128
+ export { DEFAULT_FOLDER_COLOR, DEFAULT_FOLDER_ICON, FolderIconEl, HexColorPicker, IconPicker, } from "../components/folder-style";
129
+ export { useTheme } from "../components/theme-provider";
130
+ export { VersionBadge } from "../components/version-badge";
131
+ export { useBranding } from "../contexts/BrandingContext";
132
+ export { useAreaPreferences, useUiPreference, useUiPreferencesContext, } from "../contexts/UiPreferencesContext";
133
+ export { getRegisteredDashboardCard, useRegisteredDashboardCards, } from "../dashboard/dashboard-cards-registry";
134
+ export { useActionSlot } from "../hooks/use-action-slot";
135
+ export { useInstalledPlugins } from "../hooks/use-installed-plugins";
136
+ export { usePageVisibleInterval } from "../hooks/use-page-visible-interval";
137
+ export { usePermissions } from "../hooks/use-permissions";
138
+ export { getStatusClasses, useStatusColorScheme, } from "../hooks/use-status-color-scheme";
139
+ export { useSyncStatus } from "../hooks/use-sync-status";
140
+ export { useSshAuthProviders } from "../hooks/useSshAuthProviders";
141
+ export { changeAppLanguage, normalizeLanguageCode } from "../i18n/i18n";
142
+ export { LANGUAGES } from "../i18n/languages";
143
+ export { getLiveHostStatus, useHostStatus, useServerStatus, useServerStatusMeta, } from "../lib/ServerStatusContext";
144
+ export { activityTarget } from "../lib/activity-types";
145
+ export { applyPresetSideEffects } from "../lib/apply-ui-preset";
146
+ export { getDatabaseTransferUrl } from "../lib/database-transfer-url";
147
+ export { canConfigureUpdates, type DesktopUpdateMode, desktopUpdates, type DesktopUpdateState, useDesktopUpdate, } from "../lib/desktop-updates";
148
+ export { type DocsPage, docsUrl } from "../lib/docs";
149
+ export { getErrorMessage } from "../lib/error-message";
150
+ export { getDefaultConnectionTab, resolveHostTabType, } from "../lib/host-connection-tabs";
151
+ export { DefaultsOnly, HostDefaultsContext, type HostDefaultsContextValue, HostOnly, } from "../lib/host-defaults-context";
152
+ export { invalidateHostsAndStatusCaches, invalidateServerStatusCache, } from "../lib/hosts-request-cache";
153
+ export { reportBetaFeedbackUrl, reportCoreIssueUrl } from "../lib/issue-url";
154
+ export { notifySyncChanged } from "../lib/linked-server";
155
+ export { clearLocalAdaptivePreferences, getPreferredHostAction, recordHostActionPreference, } from "../lib/local-adaptive-preferences";
156
+ export { pluginKey, pluginName } from "../lib/plugin-i18n";
157
+ export { PluginIcon } from "../lib/plugin-icon";
158
+ export { rem } from "../lib/rem";
159
+ export { getConnectedRemoteApi } from "../lib/remote-server-api";
160
+ export { roleLabel } from "../lib/role-label";
161
+ export type { StatusValue } from "../lib/server-status-store";
162
+ export { parseServerTime } from "../lib/server-time";
163
+ export { refreshSyncStatus, setSyncStatus } from "../lib/sync-status";
164
+ export { tabJumpHotkeyKeys } from "../lib/tab-jump-hotkey";
165
+ export { ACCENT_PRESET_COLORS, applyAccentColor, applyFontSize, applyUiFont, DASHBOARD_CARDS, FONT_SIZES, UI_FONTS, } from "../lib/theme";
166
+ export { registerLayout } from "../look/layout-registry";
167
+ export { useChooseTheme } from "../look/use-look-theme";
168
+ export { type AccessRecord, type ActiveSessionInfo, adminCreateUser, adminCreateUserCredential, adminCreateUserHost, adminDeleteUserCredential, adminDeleteUserHost, adminExportUserData, adminGetHostPassword, adminGetUserCredentials, adminGetUserHosts, adminResetUserPassword, adminUpdateUserCredential, adminUpdateUserHost, type ApiKey, assignRoleToUser, bulkUpdateSSHHosts, changePassword, createApiKey, createCredential, type CreatedApiKey, createRole, createSSHHost, deleteAccount, deleteAllHostsInFolder, deleteApiKey, deleteCredential, deleteOpenTab, deleteRole, deleteSSHHost, deleteUser, duplicateCredential, getActiveSessions, getApiKeys, getCredentialDetails, getCredentialSidebarPreferences, getExternalAutoProvision, getHostAccess, getHostAuthOverride, getHostPassword, getHostSidebarPreferences, getLogLevel, getPasswordLoginAllowed, getPasswordResetAllowed, getPermissionsCatalog, getRegistrationAllowed, getSecondFactorAfterExternalLogin, getSessions, getSessionTimeout, getSSHFolders, getSSHHosts, getStatusCheckSettings, getUserInfo, getUserList, getUserRoles, type LinkedAccountInfo, linkExternalToPasswordAccount, logoutUser, makeUserAdmin, type OpenTabRecord, type PermissionCatalogEntry, releaseUrlFrom, removeAdminStatus, removeRoleFromUser, renameCredentialFolder, renameFolder, reorderCredentials, reorderFolders, reorderSSHHosts, resetRecentActivity, revokeAllUserSessions, revokeHostAccess, revokeSession, type Role, saveCredentialSidebarPreferences, saveHostSidebarPreferences, setHostAuthOverride, shareFolder, shareHost, type SSHHostWithStatus, unlinkExternalFromPasswordAccount, updateCredential, updateExternalAutoProvision, updateFolderMetadata, updateHostAccess, updateLogLevel, updatePasswordLoginAllowed, updatePasswordResetAllowed, updateRegistrationAllowed, updateRole, updateSecondFactorAfterExternalLogin, updateSessionTimeout, updateSSHHost, updateStatusCheckSettings, type UserPreferences, type UserRole, } from "../main-axios";
169
+ export { MANAGE_REQUEST_EVENT, type ManageMode, type ManageRequest, requestFromLegacyEvent, requestManage, takePendingManageRequest, } from "../manage/manage-requests";
170
+ export { useSshAuthEditors } from "./auth-registry";
171
+ export { usePluginStore } from "./plugin-store";
172
+ export { shell } from "./shell-bridge";
173
+ export { OPEN_PLUGINS_EVENT } from "../plugins/open-plugins";
174
+ export { isPrerelease } from "../plugins/plugin-model";
175
+ export { usePluginHostSections } from "../settings/HostPluginSections";
176
+ export { SettingsFieldRow } from "../settings/SettingsFields";
177
+ export { LookSettings } from "../look/LookSettings";
178
+ export { useThemeOptions } from "../settings/appearance/appearance-controls";
179
+ export { hasVisibleFields, isFieldShown, } from "../settings/settings-fields-util";
180
+ export { LinkServerDialog } from "../settings/sync/LinkServerDialog";
181
+ export { ProxySettingsFields } from "../settings/sync/ProxySettingsFields";
182
+ export { useShellController } from "../shell/controller/ShellControllerProvider";
183
+ export { type KeybindingActionDef, useKeybindingActions, useKeybindingDefaults, } from "../shell/keybinding-registry";
184
+ export { filterPaletteItems, loadPaletteGroup, paletteEntriesFor, type PaletteItemDef, usePaletteEntries, usePaletteGroups, } from "../shell/palette-registry";
185
+ export { getPanel, usePanels } from "../shell/panel-registry";
186
+ export { SplitLayoutMenu } from "../shell/split/SplitLayoutMenu";
187
+ export { beginSplitDrag, endSplitDrag, isSplitDragging, moveSplitDrag, } from "../shell/split/split-drag";
188
+ export { canJoinSplit, isSplitTab, type SplitSummary, type TabSplitAction, } from "../shell/split/split-tabs";
189
+ export { openInSplit, type SplitOpenTarget, useSplitTargets, } from "../shell/split/split-targets";
190
+ export { MAX_PANES } from "../shell/split/split-tree";
191
+ export { registerTabCloseGuard } from "../shell/tab-close-guards";
192
+ export { useTabHandlesVersion } from "../shell/tab-handles";
193
+ export { getTabType, isPersistentTabType, isSessionTabType, type TabShellCallbacks, } from "../shell/tab-registry";
194
+ export { markTabSurfaceUsed, preloadTabSurface, tabIcon, } from "../shell/tabUtils";
195
+ export { AuthEnrollmentSections } from "../sidebar/AuthEnrollmentSections";
196
+ export { mapCredentials, sshHostToHost } from "../sidebar/HostManagerData";
197
+ export { getHostEditorSection, makeHostSshSubTabs, makeHostTabs, useHostEditorSections, } from "../sidebar/HostManagerTabs";
198
+ export { actionOrder, defaultConnectAction, type HostActionDef, hostActionsFor, hostBadgesFor, hostEditorToolbarItemsFor, hostMenuItemsFor, hostStatusIndicatorsFor, listHostActions, runHostAction, useHostActions, useHostBadges, useHostContextMenuItems, useHostEditorToolbarItems, useHostStatusIndicators, } from "../sidebar/host-contributions";
199
+ export { useEditorDefaultKeys } from "../sidebar/host-defaults/catalog";
200
+ export { enabledHostProtocols, type HostProtocolDef, hostProtocolFlags, type HostProtocols, listHostProtocols, protocolEnabled, protocolPort, useHostProtocols, withProtocolSettings, } from "../sidebar/host-protocols";
201
+ export { quickConnectTargets } from "../sidebar/quick-connect-host";
202
+ export { groupRailItems, isCoreRailView, moveRailItem, promotableIds, type RailGroup, type RailItemDef, railItemLabel, rightDockableIds, useRailItems, } from "../sidebar/rail-items";
@@ -6,7 +6,7 @@ import { type PluginRecord } from "./plugin-store";
6
6
  * because a disabled plugin never runs its frontend and so never registers
7
7
  * anything, yet a saved tab or card of its still has to say whose it is.
8
8
  */
9
- export type ViewKind = "tab" | "panel" | "card";
9
+ export type ViewKind = "tab" | "panel" | "card" | "layout";
10
10
  export type ViewStatus =
11
11
  /** Registered by a running plugin. */
12
12
  "ready"
@@ -0,0 +1,20 @@
1
+ import { type PluginEntry } from "./plugin-model";
2
+ export interface ConsentRequest {
3
+ plugin: PluginEntry;
4
+ mode: "install" | "update" | "upload" | "enable";
5
+ version: string;
6
+ /** What the prompt lists: all of them to install, only the new ones to update. */
7
+ capabilities: string[];
8
+ /** Set for a file uploaded in developer mode. */
9
+ uploadToken?: string;
10
+ }
11
+ /**
12
+ * Install and update consent. Capabilities read as consequences, worst first;
13
+ * the low risk ones fold into one line so the list stays short enough to read.
14
+ */
15
+ export declare function PluginConsentPrompt({ request, busy, onCancel, onConfirm, }: {
16
+ request: ConsentRequest | null;
17
+ busy?: boolean;
18
+ onCancel: () => void;
19
+ onConfirm: () => void;
20
+ }): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { type PluginEntry } from "./plugin-model";
2
+ import type { PluginsManager } from "./use-plugins-manager";
3
+ export declare function PluginDetail({ plugin, manager, onUninstalled, }: {
4
+ plugin: PluginEntry;
5
+ manager: PluginsManager;
6
+ onUninstalled: () => void;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { type PluginEntry } from "./plugin-model";
2
+ /**
3
+ * The newest version's notes, from the registry and the installed
4
+ * CHANGELOG.md, with older versions behind a toggle in a capped scroll area.
5
+ * Renders nothing when there are no versions to list.
6
+ */
7
+ export declare function PluginReleaseNotes({ plugin }: {
8
+ plugin: PluginEntry;
9
+ }): import("react").JSX.Element;
10
+ /** The plugin's YouTube video. Nothing is loaded when it has none. */
11
+ export declare function PluginVideo({ videoId, name, }: {
12
+ videoId?: string;
13
+ name: string;
14
+ }): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function PluginsTab(): import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import type { PluginsManager } from "./use-plugins-manager";
2
+ export declare function RegistriesSection({ manager }: {
3
+ manager: PluginsManager;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,23 @@
1
+ export declare function PluginIconBox({ name, size, muted, }: {
2
+ name?: string;
3
+ size?: "sm" | "md" | "lg";
4
+ muted?: boolean;
5
+ }): import("react").JSX.Element;
6
+ /** One capability as its consequence, with a mark only on the severe ones. */
7
+ export declare function CapabilityRow({ capability, showId, className, }: {
8
+ capability: string;
9
+ showId?: boolean;
10
+ className?: string;
11
+ }): import("react").JSX.Element;
12
+ /** Permanent mark on anything installed without a registry signature. */
13
+ export declare function UnverifiedBadge(): import("react").JSX.Element;
14
+ /** Marks a plugin from the community registry or a custom one. */
15
+ export declare function SourceBadge({ source, registryName, }: {
16
+ source: string;
17
+ registryName?: string | null;
18
+ }): import("react").JSX.Element;
19
+ export declare function BetaBadge(): import("react").JSX.Element;
20
+ /** How often the plugin's release files were downloaded. */
21
+ export declare function DownloadCount({ count }: {
22
+ count: number | null;
23
+ }): import("react").JSX.Element;
@@ -0,0 +1,136 @@
1
+ import { type CapabilityRisk } from "@termix-ssh/plugin-sdk/capabilities";
2
+ import type { PluginEnvVar } from "@termix-ssh/plugin-sdk/docs";
3
+ import { type ChangeType, type ChangelogChange, type ChangelogRelease } from "@termix-ssh/plugin-sdk/changelog";
4
+ import type { PluginChannel, PluginSummary, PluginUploadPreview, RegistryPluginEntry, RegistryPluginVersion } from "../api/plugins-api";
5
+ export type PluginStatus = "running" | "disabled" | "failed" | "blocked" | "server";
6
+ /** One row of the Plugins tab: what is installed merged with the registry. */
7
+ export interface PluginEntry {
8
+ id: string;
9
+ name: string;
10
+ description: string;
11
+ author: string;
12
+ category: string;
13
+ icon?: string;
14
+ repository?: string;
15
+ videoId?: string;
16
+ features: string[];
17
+ /** Docs link: the installed manifest's, else the registry's. */
18
+ docs?: string;
19
+ env: PluginEnvVar[];
20
+ installed: boolean;
21
+ version: string | null;
22
+ latestVersion: string | null;
23
+ /** Newest beta, when one is newer than stable. */
24
+ latestBeta: string | null;
25
+ channel: PluginChannel;
26
+ /** The installed copy is a beta. */
27
+ isBeta: boolean;
28
+ updateAvailable: boolean;
29
+ addedCapabilities: string[];
30
+ versions: RegistryPluginVersion[];
31
+ capabilities: string[];
32
+ status: PluginStatus | null;
33
+ enabled: boolean;
34
+ lastError: string | null;
35
+ autoUpdate: boolean;
36
+ pinnedVersion: string | null;
37
+ bundled: boolean;
38
+ inRegistry: boolean;
39
+ contributes: Record<string, unknown> | null;
40
+ publishedAt: string | null;
41
+ downloads: number | null;
42
+ source: PluginSource;
43
+ /** Installed from a file or folder with no registry signature behind it. */
44
+ unverified: boolean;
45
+ /** The registry it is listed in or was installed from. */
46
+ registryId: string | null;
47
+ registryName: string | null;
48
+ /** A linked server decides whether it runs here. */
49
+ managedByServer: boolean;
50
+ /** The app is drawn with it by default, so it can be swapped but not uninstalled. */
51
+ defaultLook: boolean;
52
+ /** Contribution keys from the manifest or the registry, like layouts. */
53
+ kinds: string[];
54
+ /** Listed, but no release runs on this build. */
55
+ unsupported: boolean;
56
+ /** The Termix range the newest release needs, when this build is too old. */
57
+ needsTermix: string | null;
58
+ }
59
+ export type PluginSource = "bundled" | "official" | "community" | "custom" | "unverified";
60
+ export declare function isPrerelease(version: string | null | undefined): boolean;
61
+ /** A beta newer than what is installed, worth offering with "Try beta". */
62
+ export declare function betaToTry(plugin: Pick<PluginEntry, "installed" | "version" | "latestBeta" | "channel">): string | null;
63
+ /** Where an installed copy came from, as the issue report names it. */
64
+ export declare function pluginSource(summary: PluginSummary): PluginSource;
65
+ export declare function pluginStatus(summary: PluginSummary): PluginStatus;
66
+ export declare function mergePlugins(installed: PluginSummary[], registry: RegistryPluginEntry[] | null): PluginEntry[];
67
+ /** A row for a file that was uploaded but not installed yet. */
68
+ export declare function uploadEntry(preview: PluginUploadPreview): PluginEntry;
69
+ export type SortKey = "popular" | "name" | "updated" | "category";
70
+ export declare function sortPlugins(rows: PluginEntry[], key: SortKey): PluginEntry[];
71
+ export declare function matchesQuery(row: PluginEntry, query: string): boolean;
72
+ export declare function categoriesOf(rows: PluginEntry[]): string[];
73
+ /** Contribution keys worth filtering by, in the order the filter lists them. */
74
+ export declare const PLUGIN_KINDS: readonly ["layouts", "themes", "tabs", "panels", "dashboardCards", "protocols", "auth", "actions", "hostCapability"];
75
+ export type PluginKind = (typeof PLUGIN_KINDS)[number];
76
+ /** The filterable kinds present in a set of rows, with how many have each. */
77
+ export declare function kindsOf(rows: PluginEntry[]): Array<{
78
+ kind: PluginKind;
79
+ count: number;
80
+ }>;
81
+ /** One page of rows, with the page clamped to what exists. */
82
+ export declare function pageOf<T>(rows: T[], page: number, size: number): {
83
+ items: T[];
84
+ page: number;
85
+ pages: number;
86
+ };
87
+ export declare function capabilityRisk(capability: string): CapabilityRisk;
88
+ /** Worst first, the order the consent copy is read in. */
89
+ export declare function orderByRisk(capabilities: string[]): string[];
90
+ export declare function isSevere(capability: string): boolean;
91
+ /** Contribution kinds worth naming in "Adds to Termix", with a count each. */
92
+ declare const CONTRIBUTION_KINDS: readonly ["tabs", "panels", "dashboardCards", "actions", "protocols", "auth", "settings", "hostCapability", "permissions", "keybindingActions", "syncEntities"];
93
+ export type ContributionKind = (typeof CONTRIBUTION_KINDS)[number];
94
+ export declare function describeContributions(contributes: Record<string, unknown> | null): Array<{
95
+ kind: ContributionKind;
96
+ count: number;
97
+ }>;
98
+ export declare function formatBytes(bytes: number): string;
99
+ /** 1234 reads as 1.2k, so the number stays a rough ranking. */
100
+ export declare function formatCount(count: number): string;
101
+ /**
102
+ * A new bug report on the plugin's own repo with what a maintainer asks first
103
+ * already filled in. Official plugins use the org bug form and the plugin
104
+ * template ships the same one. Null when the repository is not on GitHub.
105
+ */
106
+ export declare function reportIssueUrl(plugin: Pick<PluginEntry, "id" | "repository" | "version" | "latestVersion" | "status" | "source" | "lastError">, termixVersion?: string): string | null;
107
+ /**
108
+ * Beta feedback on the plugin's own repo, through the org beta form. Null when
109
+ * the repository is not on GitHub.
110
+ */
111
+ export declare function betaFeedbackUrl(plugin: Pick<PluginEntry, "id" | "repository" | "version" | "lastError">, termixVersion?: string): string | null;
112
+ /** A new feature request on the plugin's own repo, or null when not on GitHub. */
113
+ export declare function requestFeatureUrl(plugin: Pick<PluginEntry, "repository">): string | null;
114
+ /** One version in a plugin's release notes. */
115
+ export interface ReleaseRow {
116
+ version: string;
117
+ date: string | null;
118
+ summary?: string;
119
+ changes: ChangelogChange[];
120
+ /** False only for a registry version this build cannot run. */
121
+ compatible: boolean;
122
+ releaseNotesUrl?: string;
123
+ }
124
+ /**
125
+ * The registry's versions and the installed copy's CHANGELOG.md as one list,
126
+ * newest first. The installed copy's notes win for a version in both.
127
+ */
128
+ export declare function mergeReleaseNotes(versions: RegistryPluginVersion[], local: ChangelogRelease[]): ReleaseRow[];
129
+ /** The changes of one release grouped by type, in the changelog's order. */
130
+ export declare function groupChanges(changes: ChangelogChange[]): Array<{
131
+ type: ChangeType;
132
+ items: string[];
133
+ }>;
134
+ /** The embed address for a video id, or null for anything that is not one. */
135
+ export declare function youtubeEmbedUrl(videoId: string | undefined): string | null;
136
+ export {};
@@ -0,0 +1,78 @@
1
+ import { type PluginChannel } from "../api/plugins-api";
2
+ import { type PluginEntry } from "./plugin-model";
3
+ import type { ConsentRequest } from "./PluginConsentPrompt";
4
+ export declare function usePluginsManager(): {
5
+ plugins: {
6
+ name: string;
7
+ description: string;
8
+ id: string;
9
+ author: string;
10
+ category: string;
11
+ icon?: string;
12
+ repository?: string;
13
+ videoId?: string;
14
+ features: string[];
15
+ docs?: string;
16
+ env: import("@termix-ssh/plugin-sdk/docs").PluginEnvVar[];
17
+ installed: boolean;
18
+ version: string | null;
19
+ latestVersion: string | null;
20
+ latestBeta: string | null;
21
+ channel: PluginChannel;
22
+ isBeta: boolean;
23
+ updateAvailable: boolean;
24
+ addedCapabilities: string[];
25
+ versions: import("../api/plugins-api").RegistryPluginVersion[];
26
+ capabilities: string[];
27
+ status: import("./plugin-model").PluginStatus | null;
28
+ enabled: boolean;
29
+ lastError: string | null;
30
+ autoUpdate: boolean;
31
+ pinnedVersion: string | null;
32
+ bundled: boolean;
33
+ inRegistry: boolean;
34
+ contributes: Record<string, unknown> | null;
35
+ publishedAt: string | null;
36
+ downloads: number | null;
37
+ source: import("./plugin-model").PluginSource;
38
+ unverified: boolean;
39
+ registryId: string | null;
40
+ registryName: string | null;
41
+ managedByServer: boolean;
42
+ defaultLook: boolean;
43
+ kinds: string[];
44
+ unsupported: boolean;
45
+ needsTermix: string | null;
46
+ }[];
47
+ loading: boolean;
48
+ refreshing: boolean;
49
+ registryError: string;
50
+ managedByServer: boolean;
51
+ lastCheckedAt: string;
52
+ registries: import("../api/plugins-api").RegistryListingSource[];
53
+ reload: () => Promise<void>;
54
+ busy: Set<string>;
55
+ consent: ConsentRequest;
56
+ setConsent: import("react").Dispatch<import("react").SetStateAction<ConsentRequest>>;
57
+ developerMode: boolean;
58
+ signedOnly: boolean;
59
+ requestUpload: (file: File) => Promise<void>;
60
+ refresh: () => Promise<void>;
61
+ requestInstall: (plugin: PluginEntry, version?: string) => void;
62
+ requestUpdate: (plugin: PluginEntry, version?: string) => Promise<void>;
63
+ confirmConsent: () => Promise<void>;
64
+ toggle: (plugin: PluginEntry) => Promise<void>;
65
+ retry: (plugin: PluginEntry) => Promise<void>;
66
+ uninstall: (plugin: PluginEntry) => Promise<boolean>;
67
+ removeData: (plugin: PluginEntry) => Promise<boolean>;
68
+ setOptions: (plugin: PluginEntry, options: {
69
+ autoUpdate?: boolean;
70
+ pinned?: boolean;
71
+ channel?: PluginChannel;
72
+ }) => Promise<void>;
73
+ tryBeta: (plugin: PluginEntry) => Promise<void>;
74
+ leaveBeta: (plugin: PluginEntry) => Promise<void>;
75
+ setAllChannels: (channel: PluginChannel) => Promise<void>;
76
+ updateAll: () => Promise<void>;
77
+ };
78
+ export type PluginsManager = ReturnType<typeof usePluginsManager>;