@termix-ssh/plugin-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -0
- package/cli/commands/build.mjs +246 -0
- package/cli/commands/migrations.mjs +248 -0
- package/cli/commands/pack.mjs +42 -0
- package/cli/commands/sign.mjs +83 -0
- package/cli/commands/test.mjs +33 -0
- package/cli/commands/validate.mjs +215 -0
- package/cli/index.mjs +65 -0
- package/cli/lib/changelog.mjs +126 -0
- package/cli/lib/externals.mjs +46 -0
- package/cli/lib/plugin-dir.mjs +29 -0
- package/cli/lib/signing.mjs +86 -0
- package/cli/lib/static-url-imports.mjs +54 -0
- package/cli/lib/tmxplug.mjs +106 -0
- package/cli/patches/guacamole-common-js-flush.cjs +76 -0
- package/cli/patches/xterm-android-ime.cjs +130 -0
- package/client.d.ts +13 -0
- package/dist/backend.d.ts +1777 -0
- package/dist/backend.js +84 -0
- package/dist/capabilities.d.ts +38 -0
- package/dist/capabilities.js +71 -0
- package/dist/db.d.ts +112 -0
- package/dist/db.js +189 -0
- package/dist/ddl.d.ts +76 -0
- package/dist/ddl.js +678 -0
- package/dist/desktop.d.ts +346 -0
- package/dist/desktop.js +5 -0
- package/dist/frontend.d.ts +1206 -0
- package/dist/frontend.js +388 -0
- package/dist/host/chunk-F3SDZDDG.js +6017 -0
- package/dist/host/chunk-XGWE7BTJ.js +90 -0
- package/dist/host/chunk-XH5NXL6Y.js +56314 -0
- package/dist/host/chunk-YC2MAKSP.js +14 -0
- package/dist/host/linked-server-FZGWQW32.js +12 -0
- package/dist/host/rbac-api-6KDMBVDZ.js +52 -0
- package/dist/host/testing-host.js +414 -0
- package/dist/host/theme.css +91 -0
- package/dist/host/types/src/types/auth-protocols.d.ts +10 -0
- package/dist/host/types/src/types/connection-log.d.ts +13 -0
- package/dist/host/types/src/types/credential-sidebar-preferences.d.ts +38 -0
- package/dist/host/types/src/types/host-defaults.d.ts +60 -0
- package/dist/host/types/src/types/host-sidebar-preferences.d.ts +55 -0
- package/dist/host/types/src/types/index.d.ts +298 -0
- package/dist/host/types/src/types/keybindings.d.ts +27 -0
- package/dist/host/types/src/types/ui-preferences.d.ts +102 -0
- package/dist/host/types/src/types/ui-types.d.ts +260 -0
- package/dist/host/types/src/ui/api/admin-user-data-api.d.ts +11 -0
- package/dist/host/types/src/ui/api/auth-methods-api.d.ts +63 -0
- package/dist/host/types/src/ui/api/credential-sidebar-preferences-api.d.ts +3 -0
- package/dist/host/types/src/ui/api/credentials-api.d.ts +56 -0
- package/dist/host/types/src/ui/api/dashboard-api.d.ts +23 -0
- package/dist/host/types/src/ui/api/external-account-api.d.ts +8 -0
- package/dist/host/types/src/ui/api/host-sidebar-preferences-api.d.ts +3 -0
- package/dist/host/types/src/ui/api/host-status-api.d.ts +11 -0
- package/dist/host/types/src/ui/api/open-tabs-api.d.ts +74 -0
- package/dist/host/types/src/ui/api/plugins-api.d.ts +128 -0
- package/dist/host/types/src/ui/api/rbac-api.d.ts +167 -0
- package/dist/host/types/src/ui/api/settings-api.d.ts +22 -0
- package/dist/host/types/src/ui/api/ssh-host-management-api.d.ts +65 -0
- package/dist/host/types/src/ui/api/sync-api.d.ts +93 -0
- package/dist/host/types/src/ui/api/system-status-api.d.ts +49 -0
- package/dist/host/types/src/ui/api/ui-preferences-api.d.ts +8 -0
- package/dist/host/types/src/ui/api/user-management-api.d.ts +80 -0
- package/dist/host/types/src/ui/auth/Auth.d.ts +12 -0
- package/dist/host/types/src/ui/auth/auth-bits.d.ts +11 -0
- package/dist/host/types/src/ui/auth/silent-signin.d.ts +2 -0
- package/dist/host/types/src/ui/components/FullScreenAppWrapper.d.ts +9 -0
- package/dist/host/types/src/ui/components/alert-dialog.d.ts +14 -0
- package/dist/host/types/src/ui/components/alert.d.ts +9 -0
- package/dist/host/types/src/ui/components/badge.d.ts +9 -0
- package/dist/host/types/src/ui/components/button.d.ts +13 -0
- package/dist/host/types/src/ui/components/card-grid/CardGridCanvas.d.ts +22 -0
- package/dist/host/types/src/ui/components/card-grid/layout-utils.d.ts +26 -0
- package/dist/host/types/src/ui/components/card-grid/types.d.ts +29 -0
- package/dist/host/types/src/ui/components/card-masonry.d.ts +16 -0
- package/dist/host/types/src/ui/components/card.d.ts +11 -0
- package/dist/host/types/src/ui/components/charts/BarSeries.d.ts +16 -0
- package/dist/host/types/src/ui/components/charts/LineChart.d.ts +17 -0
- package/dist/host/types/src/ui/components/charts/RadialGauge.d.ts +18 -0
- package/dist/host/types/src/ui/components/charts/Sparkline.d.ts +22 -0
- package/dist/host/types/src/ui/components/charts/StatRow.d.ts +15 -0
- package/dist/host/types/src/ui/components/charts/geometry.d.ts +20 -0
- package/dist/host/types/src/ui/components/charts/index.d.ts +4 -0
- package/dist/host/types/src/ui/components/checkbox.d.ts +4 -0
- package/dist/host/types/src/ui/components/connection/ConnectionGate.d.ts +56 -0
- package/dist/host/types/src/ui/components/connection/ConnectionLogPanel.d.ts +9 -0
- package/dist/host/types/src/ui/components/connection/ConnectionScreen.d.ts +34 -0
- package/dist/host/types/src/ui/components/connection/connection-status.d.ts +1 -0
- package/dist/host/types/src/ui/components/data-view.d.ts +32 -0
- package/dist/host/types/src/ui/components/dialog.d.ts +17 -0
- package/dist/host/types/src/ui/components/dropdown-menu.d.ts +29 -0
- package/dist/host/types/src/ui/components/empty-state.d.ts +19 -0
- package/dist/host/types/src/ui/components/form-fields.d.ts +115 -0
- package/dist/host/types/src/ui/components/input.d.ts +3 -0
- package/dist/host/types/src/ui/components/kbd.d.ts +12 -0
- package/dist/host/types/src/ui/components/label.d.ts +4 -0
- package/dist/host/types/src/ui/components/manager-card.d.ts +25 -0
- package/dist/host/types/src/ui/components/meter.d.ts +14 -0
- package/dist/host/types/src/ui/components/metric-card.d.ts +18 -0
- package/dist/host/types/src/ui/components/panel-layout.d.ts +83 -0
- package/dist/host/types/src/ui/components/password-input.d.ts +4 -0
- package/dist/host/types/src/ui/components/popover.d.ts +7 -0
- package/dist/host/types/src/ui/components/scroll-area.d.ts +5 -0
- package/dist/host/types/src/ui/components/section-card.d.ts +29 -0
- package/dist/host/types/src/ui/components/select.d.ts +15 -0
- package/dist/host/types/src/ui/components/select2.d.ts +8 -0
- package/dist/host/types/src/ui/components/separator.d.ts +4 -0
- package/dist/host/types/src/ui/components/sheet.d.ts +14 -0
- package/dist/host/types/src/ui/components/sidebar.d.ts +69 -0
- package/dist/host/types/src/ui/components/skeleton.d.ts +2 -0
- package/dist/host/types/src/ui/components/slider.d.ts +4 -0
- package/dist/host/types/src/ui/components/sonner.d.ts +4 -0
- package/dist/host/types/src/ui/components/surface/prompt-styles.d.ts +4 -0
- package/dist/host/types/src/ui/components/surface/surface-scope.d.ts +79 -0
- package/dist/host/types/src/ui/components/switch.d.ts +4 -0
- package/dist/host/types/src/ui/components/tab-strip.d.ts +19 -0
- package/dist/host/types/src/ui/components/tabs.d.ts +7 -0
- package/dist/host/types/src/ui/components/textarea.d.ts +4 -0
- package/dist/host/types/src/ui/components/theme-provider.d.ts +14 -0
- package/dist/host/types/src/ui/components/tooltip.d.ts +7 -0
- package/dist/host/types/src/ui/contexts/BrandingContext.d.ts +15 -0
- package/dist/host/types/src/ui/contexts/UiPreferencesContext.d.ts +38 -0
- package/dist/host/types/src/ui/contexts/branding-document.d.ts +10 -0
- package/dist/host/types/src/ui/dashboard/dashboard-cards-registry.d.ts +30 -0
- package/dist/host/types/src/ui/hooks/use-action-slot.d.ts +10 -0
- package/dist/host/types/src/ui/hooks/use-adaptive-polling.d.ts +5 -0
- package/dist/host/types/src/ui/hooks/use-mobile.d.ts +1 -0
- package/dist/host/types/src/ui/hooks/use-permissions.d.ts +29 -0
- package/dist/host/types/src/ui/hooks/use-status-color-scheme.d.ts +12 -0
- package/dist/host/types/src/ui/hooks/use-sync-status.d.ts +4 -0
- package/dist/host/types/src/ui/hooks/useSshAuthProviders.d.ts +17 -0
- package/dist/host/types/src/ui/i18n/i18n.d.ts +52 -0
- package/dist/host/types/src/ui/lib/ServerStatusContext.d.ts +33 -0
- package/dist/host/types/src/ui/lib/adaptive-polling.d.ts +29 -0
- package/dist/host/types/src/ui/lib/adaptive-resource-budget.d.ts +39 -0
- package/dist/host/types/src/ui/lib/app-keyboard-shortcuts.d.ts +8 -0
- package/dist/host/types/src/ui/lib/base-path.d.ts +1 -0
- package/dist/host/types/src/ui/lib/clipboard-provider.d.ts +9 -0
- package/dist/host/types/src/ui/lib/clipboard.d.ts +20 -0
- package/dist/host/types/src/ui/lib/connection-origin.d.ts +47 -0
- package/dist/host/types/src/ui/lib/db-health-monitor.d.ts +34 -0
- package/dist/host/types/src/ui/lib/device-id.d.ts +1 -0
- package/dist/host/types/src/ui/lib/electron.d.ts +1 -0
- package/dist/host/types/src/ui/lib/embedded-server-status.d.ts +15 -0
- package/dist/host/types/src/ui/lib/error-message.d.ts +9 -0
- package/dist/host/types/src/ui/lib/frontend-logger.d.ts +67 -0
- package/dist/host/types/src/ui/lib/global-shortcut-handler.d.ts +3 -0
- package/dist/host/types/src/ui/lib/host-defaults-context.d.ts +48 -0
- package/dist/host/types/src/ui/lib/hosts-request-cache.d.ts +9 -0
- package/dist/host/types/src/ui/lib/keybinding-match.d.ts +3 -0
- package/dist/host/types/src/ui/lib/linked-server.d.ts +10 -0
- package/dist/host/types/src/ui/lib/local-adaptive-engine.d.ts +40 -0
- package/dist/host/types/src/ui/lib/permissions.d.ts +16 -0
- package/dist/host/types/src/ui/lib/plugin-i18n.d.ts +11 -0
- package/dist/host/types/src/ui/lib/plugin-icon.d.ts +11 -0
- package/dist/host/types/src/ui/lib/plugin-transport.d.ts +50 -0
- package/dist/host/types/src/ui/lib/registry.d.ts +29 -0
- package/dist/host/types/src/ui/lib/rem.d.ts +7 -0
- package/dist/host/types/src/ui/lib/remote-server-api.d.ts +11 -0
- package/dist/host/types/src/ui/lib/server-status-store.d.ts +37 -0
- package/dist/host/types/src/ui/lib/sync-events.d.ts +2 -0
- package/dist/host/types/src/ui/lib/sync-status.d.ts +6 -0
- package/dist/host/types/src/ui/lib/tab-jump-hotkey.d.ts +4 -0
- package/dist/host/types/src/ui/lib/theme.d.ts +21 -0
- package/dist/host/types/src/ui/lib/ttl-request-cache.d.ts +10 -0
- package/dist/host/types/src/ui/lib/usage-color.d.ts +5 -0
- package/dist/host/types/src/ui/lib/utils.d.ts +2 -0
- package/dist/host/types/src/ui/lib/visible-interval.d.ts +5 -0
- package/dist/host/types/src/ui/lib/widget-title.d.ts +8 -0
- package/dist/host/types/src/ui/lib/ws-auth.d.ts +1 -0
- package/dist/host/types/src/ui/main-axios.d.ts +170 -0
- package/dist/host/types/src/ui/plugin-host/PluginViewPlaceholder.d.ts +13 -0
- package/dist/host/types/src/ui/plugin-host/app.d.ts +18 -0
- package/dist/host/types/src/ui/plugin-host/auth-registry.d.ts +50 -0
- package/dist/host/types/src/ui/plugin-host/bridge.d.ts +26 -0
- package/dist/host/types/src/ui/plugin-host/component-registry.d.ts +24 -0
- package/dist/host/types/src/ui/plugin-host/desktop.d.ts +7 -0
- package/dist/host/types/src/ui/plugin-host/extension-registry.d.ts +16 -0
- package/dist/host/types/src/ui/plugin-host/host-scope.d.ts +26 -0
- package/dist/host/types/src/ui/plugin-host/loader.d.ts +52 -0
- package/dist/host/types/src/ui/plugin-host/plugin-store.d.ts +40 -0
- package/dist/host/types/src/ui/plugin-host/scope.d.ts +20 -0
- package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +99 -0
- package/dist/host/types/src/ui/plugin-host/shell-bridge.d.ts +67 -0
- package/dist/host/types/src/ui/plugin-host/view-ownership.d.ts +31 -0
- package/dist/host/types/src/ui/settings/HostPluginSections.d.ts +31 -0
- package/dist/host/types/src/ui/settings/SettingsFields.d.ts +22 -0
- package/dist/host/types/src/ui/settings/host-feature-tabs.d.ts +11 -0
- package/dist/host/types/src/ui/settings/settings-components.d.ts +32 -0
- package/dist/host/types/src/ui/settings/settings-fields-util.d.ts +11 -0
- package/dist/host/types/src/ui/shell/ActionSlot.d.ts +41 -0
- package/dist/host/types/src/ui/shell/TabContext.d.ts +30 -0
- package/dist/host/types/src/ui/shell/action-registry.d.ts +99 -0
- package/dist/host/types/src/ui/shell/keybinding-registry.d.ts +62 -0
- package/dist/host/types/src/ui/shell/palette-registry.d.ts +55 -0
- package/dist/host/types/src/ui/shell/panel-registry.d.ts +24 -0
- package/dist/host/types/src/ui/shell/tab-registry.d.ts +92 -0
- package/dist/host/types/src/ui/sidebar/HostManagerTabs.d.ts +65 -0
- package/dist/host/types/src/ui/sidebar/host-contributions.d.ts +72 -0
- package/dist/host/types/src/ui/sidebar/host-defaults/catalog.d.ts +17 -0
- package/dist/host/types/src/ui/sidebar/host-protocols.d.ts +49 -0
- package/dist/host/types/src/ui/sidebar/quick-connect-host.d.ts +21 -0
- package/dist/host/types/src/ui/sidebar/rail-items.d.ts +103 -0
- package/dist/host/types/src/ui/ssh/connection-log/ConnectionLogContext.d.ts +17 -0
- package/dist/host/types/src/ui/ssh/dialogs/BrowserSignInDialog.d.ts +18 -0
- package/dist/host/types/src/ui/ssh/dialogs/HostKeyVerificationDialog.d.ts +17 -0
- package/dist/host/types/src/ui/ssh/dialogs/PassphraseDialog.d.ts +15 -0
- package/dist/host/types/src/ui/ssh/dialogs/SSHAuthDialog.d.ts +20 -0
- package/dist/host/types/src/ui/ssh/dialogs/TOTPDialog.d.ts +13 -0
- package/dist/host/ui.d.ts +1 -0
- package/dist/host/ui.js +31754 -0
- package/dist/host/use-permissions-NULZL43J.js +18 -0
- package/dist/host-commands.d.ts +89 -0
- package/dist/host-commands.js +387 -0
- package/dist/manifest.d.ts +461 -0
- package/dist/manifest.js +1499 -0
- package/dist/settings.d.ts +43 -0
- package/dist/settings.js +168 -0
- package/dist/ssh-certs.d.ts +25 -0
- package/dist/ssh-certs.js +234 -0
- package/dist/ssh-options.d.ts +23 -0
- package/dist/ssh-options.js +1 -0
- package/dist/table-builder.d.ts +26 -0
- package/dist/table-builder.js +87 -0
- package/dist/testing/safe-ports.d.ts +10 -0
- package/dist/testing/safe-ports.js +59 -0
- package/dist/testing/setup.d.ts +7 -0
- package/dist/testing/setup.js +146 -0
- package/dist/testing.d.ts +537 -0
- package/dist/testing.js +1451 -0
- package/dist/vitest-preset.d.ts +54 -0
- package/dist/vitest-preset.js +96 -0
- package/package.json +143 -0
- package/schema/changelog.schema.json +67 -0
- package/schema/manifest.schema.json +1160 -0
- package/tsconfig.plugin.json +31 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface AdaptivePollingPolicy {
|
|
2
|
+
minIntervalMs: number;
|
|
3
|
+
maxIntervalMs: number;
|
|
4
|
+
stablePollsPerStep?: number;
|
|
5
|
+
jitterRatio?: number;
|
|
6
|
+
/** Prevent expensive requests from consuming more than this share of time. */
|
|
7
|
+
maxRequestDutyCycle?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface AdaptivePollingState {
|
|
10
|
+
stablePolls: number;
|
|
11
|
+
consecutiveFailures: number;
|
|
12
|
+
lastPollDurationMs?: number;
|
|
13
|
+
}
|
|
14
|
+
export type AdaptivePollResult = boolean | void;
|
|
15
|
+
export declare function computeAdaptivePollDelay(policy: AdaptivePollingPolicy, state: AdaptivePollingState, random?: () => number): number;
|
|
16
|
+
export declare function runAdaptivePolling(poll: () => AdaptivePollResult | Promise<AdaptivePollResult>, policy: AdaptivePollingPolicy, options?: {
|
|
17
|
+
enabled?: () => boolean;
|
|
18
|
+
visible?: () => boolean;
|
|
19
|
+
runImmediately?: boolean;
|
|
20
|
+
random?: () => number;
|
|
21
|
+
intervalMultiplier?: () => number;
|
|
22
|
+
onError?: (error: unknown) => void;
|
|
23
|
+
}): () => void;
|
|
24
|
+
interface NetworkInformationLike {
|
|
25
|
+
saveData?: boolean;
|
|
26
|
+
effectiveType?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function getPollingEnvironmentMultiplier(connection?: NetworkInformationLike): number;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type AdaptiveTaskKind = "module" | "network";
|
|
2
|
+
export type AdaptiveResourceTier = "paused" | "constrained" | "balanced" | "eager";
|
|
3
|
+
export interface AdaptiveResourceEnvironment {
|
|
4
|
+
visible: boolean;
|
|
5
|
+
saveData?: boolean;
|
|
6
|
+
effectiveType?: string;
|
|
7
|
+
deviceMemoryGb?: number;
|
|
8
|
+
hardwareConcurrency?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface AdaptiveResourceFeedback {
|
|
11
|
+
observations: number;
|
|
12
|
+
successes: number;
|
|
13
|
+
cancellations: number;
|
|
14
|
+
fallbacks: number;
|
|
15
|
+
latencyEwmaMs?: number;
|
|
16
|
+
usefulnessObservations?: number;
|
|
17
|
+
usefulPreloads?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface AdaptiveResourceBudget {
|
|
20
|
+
tier: AdaptiveResourceTier;
|
|
21
|
+
allowModulePreload: boolean;
|
|
22
|
+
allowNetworkPrefetch: boolean;
|
|
23
|
+
maxPrefetchBytes: number;
|
|
24
|
+
maxConcurrentModulePreloads: number;
|
|
25
|
+
maxConcurrentNetworkPrefetches: number;
|
|
26
|
+
reason: "hidden" | "environment" | "feedback" | "default";
|
|
27
|
+
}
|
|
28
|
+
/** Marks that foreground navigation consumed a recent speculative preload. */
|
|
29
|
+
export declare function markAdaptiveResourceUsed(kind: AdaptiveTaskKind, action: string, now?: number): void;
|
|
30
|
+
/** Drops in-flight bookkeeping. Intended for tests and hard session resets. */
|
|
31
|
+
export declare function resetAdaptiveResourceState(): void;
|
|
32
|
+
export declare function computeAdaptiveResourceBudget(environment: AdaptiveResourceEnvironment, feedback?: AdaptiveResourceFeedback): AdaptiveResourceBudget;
|
|
33
|
+
export declare function getAdaptiveResourceBudget(kind: AdaptiveTaskKind): AdaptiveResourceBudget;
|
|
34
|
+
interface AdaptiveTaskOptions {
|
|
35
|
+
estimatedBytes?: number;
|
|
36
|
+
}
|
|
37
|
+
/** Starts optional work only when it fits the current local resource budget. */
|
|
38
|
+
export declare function runAdaptiveBackgroundTask(kind: AdaptiveTaskKind, action: string, task: () => Promise<unknown>, options?: AdaptiveTaskOptions): boolean;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function isShiftKey(event: Pick<KeyboardEvent, "key" | "code">): boolean;
|
|
2
|
+
export declare function getAltDigitShortcut(event: Pick<KeyboardEvent, "key" | "code">): number;
|
|
3
|
+
export declare function dispatchCtrlW(target: EventTarget | null): boolean;
|
|
4
|
+
/** Match two consecutive Shift presses, never a typing or IME sequence. */
|
|
5
|
+
export declare function createCommandPaletteShortcutMatcher(): {
|
|
6
|
+
matches: (event: KeyboardEvent, now?: number) => boolean;
|
|
7
|
+
reset: () => void;
|
|
8
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getBasePath(): string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IClipboardProvider, ClipboardSelectionType } from "@xterm/addon-clipboard";
|
|
2
|
+
export declare class RobustClipboardProvider implements IClipboardProvider {
|
|
3
|
+
private pendingWrite;
|
|
4
|
+
private readonly focusHandler;
|
|
5
|
+
constructor();
|
|
6
|
+
dispose(): void;
|
|
7
|
+
readText(_selection: ClipboardSelectionType): string | Promise<string>;
|
|
8
|
+
writeText(_selection: ClipboardSelectionType, text: string): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copies text to the clipboard, working around environments where the async
|
|
3
|
+
* Clipboard API is unavailable - notably Brave and any non-HTTPS origin, where
|
|
4
|
+
* `navigator.clipboard` is undefined. Tries the Electron bridge first, then the
|
|
5
|
+
* async Clipboard API, then a hidden-textarea execCommand fallback.
|
|
6
|
+
*
|
|
7
|
+
* Returns true on success so callers can decide whether to show a success or
|
|
8
|
+
* error toast.
|
|
9
|
+
*/
|
|
10
|
+
export declare function copyToClipboard(text: string): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Reads text from the clipboard, working around environments where the async
|
|
13
|
+
* Clipboard API is unavailable - notably any non-HTTPS origin, where
|
|
14
|
+
* `navigator.clipboard.readText` is undefined. Tries the Electron bridge
|
|
15
|
+
* first, then the async Clipboard API, then a hidden-textarea execCommand
|
|
16
|
+
* fallback (which still works over plain HTTP in Chromium-based browsers).
|
|
17
|
+
*
|
|
18
|
+
* Returns an empty string if every approach fails.
|
|
19
|
+
*/
|
|
20
|
+
export declare function readFromClipboard(): Promise<string>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type ConnectionOrigin = "local" | "remote";
|
|
2
|
+
interface OriginResolvableHost {
|
|
3
|
+
connectionOrigin?: ConnectionOrigin | null;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Resolves which backend a given host's interactive connection (SSH, Docker
|
|
7
|
+
* console, remote desktop) should dial: the desktop app's embedded local
|
|
8
|
+
* backend, or the server it is linked to. A plugin whose connection is
|
|
9
|
+
* always local regardless of this setting (serial: the hardware is
|
|
10
|
+
* physically attached to this desktop machine) skips this helper entirely
|
|
11
|
+
* and calls app.wsUrl() without an origin option, which defaults to "local".
|
|
12
|
+
*
|
|
13
|
+
* Everything else follows the host's own override if set, falling back to
|
|
14
|
+
* the desktop-wide default.
|
|
15
|
+
*
|
|
16
|
+
* `defaultRemote` makes a host left on Default resolve to "remote" instead of
|
|
17
|
+
* following the desktop-wide setting. Remote desktop passes it: it needs a
|
|
18
|
+
* guacd, which the desktop does not ship, so originating it here only works
|
|
19
|
+
* once the user has pointed Termix at one of their own. Making that opt-in
|
|
20
|
+
* per host keeps an upgrade from moving working connections onto a guacd
|
|
21
|
+
* that isn't there -- see Termix-SSH/Support#1240.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveConnectionOrigin(host: OriginResolvableHost, options?: {
|
|
24
|
+
defaultRemote?: boolean;
|
|
25
|
+
}): Promise<ConnectionOrigin>;
|
|
26
|
+
export interface RemoteConnectionTarget {
|
|
27
|
+
serverUrl: string;
|
|
28
|
+
jwt: string | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds the base WebSocket URL for an interactive connection protocol,
|
|
32
|
+
* given a resolved origin. Returns null when origin is "remote" but this
|
|
33
|
+
* desktop is not linked to a server -- callers must show a blocking message
|
|
34
|
+
* rather than attempting to connect.
|
|
35
|
+
*/
|
|
36
|
+
export interface WebSocketConnectionTarget {
|
|
37
|
+
url: string;
|
|
38
|
+
protocols: string[];
|
|
39
|
+
}
|
|
40
|
+
export declare function buildOriginWsUrl({ origin, localPort, localPath, remotePath, includeJwt, }: {
|
|
41
|
+
origin: ConnectionOrigin;
|
|
42
|
+
localPort: number;
|
|
43
|
+
localPath: string;
|
|
44
|
+
remotePath: string;
|
|
45
|
+
includeJwt?: boolean;
|
|
46
|
+
}): Promise<WebSocketConnectionTarget | null>;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatabaseHealthMonitor
|
|
3
|
+
*
|
|
4
|
+
* Non-blocking health tracker for backend/database connectivity. The
|
|
5
|
+
* monitor no longer gates the whole UI: there is no full-screen overlay.
|
|
6
|
+
* When a transient failure is observed we emit a "degraded" event so the
|
|
7
|
+
* UI can surface a persistent but non-intrusive toast. A success from any
|
|
8
|
+
* API request clears the state. Session-expired events are also relayed
|
|
9
|
+
* to the UI.
|
|
10
|
+
*
|
|
11
|
+
* The previous "database-connection-lost" / "database-connection-restored"
|
|
12
|
+
* events have been retired along with the overlay. Listeners should use
|
|
13
|
+
* "database-connection-degraded" / "database-connection-degraded-cleared"
|
|
14
|
+
* to reflect the current UX contract: users can keep working regardless
|
|
15
|
+
* of backend hiccups and are simply informed via a toast.
|
|
16
|
+
*/
|
|
17
|
+
type EventListener = (...args: unknown[]) => void;
|
|
18
|
+
declare class DatabaseHealthMonitor {
|
|
19
|
+
private static instance;
|
|
20
|
+
private listeners;
|
|
21
|
+
private degradedActive;
|
|
22
|
+
private constructor();
|
|
23
|
+
static getInstance(): DatabaseHealthMonitor;
|
|
24
|
+
on(event: string, listener: EventListener): void;
|
|
25
|
+
off(event: string, listener: EventListener): void;
|
|
26
|
+
private emit;
|
|
27
|
+
reportSessionExpired(): void;
|
|
28
|
+
reportDatabaseError(error: unknown): void;
|
|
29
|
+
reportDatabaseSuccess(): void;
|
|
30
|
+
isDegraded(): boolean;
|
|
31
|
+
reset(): void;
|
|
32
|
+
}
|
|
33
|
+
export declare const dbHealthMonitor: DatabaseHealthMonitor;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getDeviceId(): string | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isElectron(): boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type EmbeddedServerFailureReason = "port-in-use" | "crashed";
|
|
2
|
+
export interface EmbeddedServerFailure {
|
|
3
|
+
reason: EmbeddedServerFailureReason;
|
|
4
|
+
port: number | null;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Asks the Electron main process whether the embedded backend has failed for
|
|
8
|
+
* good.
|
|
9
|
+
*
|
|
10
|
+
* Returns null in every case where waiting is still the right thing to do:
|
|
11
|
+
* outside Electron, while the backend is only slow to boot, and on a desktop
|
|
12
|
+
* build old enough not to expose the channel at all. A non-null result means
|
|
13
|
+
* the backend process is gone and no amount of retrying will bring it back.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getEmbeddedServerFailure(): Promise<EmbeddedServerFailure | null>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract a stable, human-readable message from an unknown thrown value.
|
|
3
|
+
*
|
|
4
|
+
* A thrown value is not guaranteed to be an `Error` — libraries may throw
|
|
5
|
+
* strings or plain objects, which carry no useful `.message`. When that
|
|
6
|
+
* happens the caller gets `fallback` instead, so error paths never surface a
|
|
7
|
+
* raw `[object Object]` in logs or UI.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getErrorMessage(error: unknown, fallback?: string): string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type LogLevel = "debug" | "info" | "warn" | "error" | "success";
|
|
2
|
+
export interface LogContext {
|
|
3
|
+
operation?: string;
|
|
4
|
+
userId?: string;
|
|
5
|
+
hostId?: number;
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
requestId?: string;
|
|
8
|
+
duration?: number;
|
|
9
|
+
method?: string;
|
|
10
|
+
url?: string;
|
|
11
|
+
status?: number;
|
|
12
|
+
statusText?: string;
|
|
13
|
+
responseTime?: number;
|
|
14
|
+
retryCount?: number;
|
|
15
|
+
errorCode?: string;
|
|
16
|
+
errorMessage?: string;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
declare class FrontendLogger {
|
|
20
|
+
private serviceName;
|
|
21
|
+
private serviceIcon;
|
|
22
|
+
private serviceColor;
|
|
23
|
+
private isDevelopment;
|
|
24
|
+
constructor(serviceName: string, serviceIcon: string, serviceColor: string);
|
|
25
|
+
private getTimeStamp;
|
|
26
|
+
private formatMessage;
|
|
27
|
+
private getLevelTag;
|
|
28
|
+
private getServiceTag;
|
|
29
|
+
private shouldLog;
|
|
30
|
+
private log;
|
|
31
|
+
debug(message: string, context?: LogContext): void;
|
|
32
|
+
info(message: string, context?: LogContext): void;
|
|
33
|
+
warn(message: string, context?: LogContext): void;
|
|
34
|
+
error(message: string, error?: unknown, context?: LogContext): void;
|
|
35
|
+
success(message: string, context?: LogContext): void;
|
|
36
|
+
api(message: string, context?: LogContext): void;
|
|
37
|
+
request(message: string, context?: LogContext): void;
|
|
38
|
+
response(message: string, context?: LogContext): void;
|
|
39
|
+
auth(message: string, context?: LogContext): void;
|
|
40
|
+
ssh(message: string, context?: LogContext): void;
|
|
41
|
+
file(message: string, context?: LogContext): void;
|
|
42
|
+
connection(message: string, context?: LogContext): void;
|
|
43
|
+
disconnect(message: string, context?: LogContext): void;
|
|
44
|
+
retry(message: string, context?: LogContext): void;
|
|
45
|
+
performance(message: string, context?: LogContext): void;
|
|
46
|
+
security(message: string, context?: LogContext): void;
|
|
47
|
+
requestStart(method: string, url: string, context?: LogContext): void;
|
|
48
|
+
requestSuccess(method: string, url: string, status: number, responseTime: number, context?: LogContext): void;
|
|
49
|
+
requestError(method: string, url: string, status: number, errorMessage: string, responseTime?: number, context?: LogContext): void;
|
|
50
|
+
networkError(method: string, url: string, errorMessage: string, context?: LogContext): void;
|
|
51
|
+
authError(method: string, url: string, context?: LogContext): void;
|
|
52
|
+
retryAttempt(method: string, url: string, attempt: number, maxAttempts: number, context?: LogContext): void;
|
|
53
|
+
apiOperation(operation: string, details: string, context?: LogContext): void;
|
|
54
|
+
requestSummary(method: string, url: string, status: number, responseTime: number, context?: LogContext): void;
|
|
55
|
+
private getShortUrl;
|
|
56
|
+
private getStatusIcon;
|
|
57
|
+
private getPerformanceIcon;
|
|
58
|
+
private sanitizeUrl;
|
|
59
|
+
}
|
|
60
|
+
export declare const apiLogger: FrontendLogger;
|
|
61
|
+
export declare const authLogger: FrontendLogger;
|
|
62
|
+
export declare const sshLogger: FrontendLogger;
|
|
63
|
+
export declare const fileLogger: FrontendLogger;
|
|
64
|
+
export declare const dashboardLogger: FrontendLogger;
|
|
65
|
+
/** A named console logger, for plugins that want the same log format. */
|
|
66
|
+
export declare function createFrontendLogger(serviceName: string, serviceIcon?: string, serviceColor?: string): FrontendLogger;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host editor's view of host defaults, for the fields it draws.
|
|
3
|
+
*
|
|
4
|
+
* In a host, a field either follows its default (and says where from) or is
|
|
5
|
+
* the host's own (and can be reset). In the defaults editor, a field is either
|
|
6
|
+
* set at the level being edited (and can be cleared) or shows what it
|
|
7
|
+
* inherits. Outside either editor there is no provider and nothing renders.
|
|
8
|
+
*/
|
|
9
|
+
import type { HostDefaultSource, HostDefaultsLevel } from "../../types/host-defaults";
|
|
10
|
+
export interface HostDefaultsContextValue {
|
|
11
|
+
mode: "host" | "defaults";
|
|
12
|
+
/** The level being edited, in the defaults editor. */
|
|
13
|
+
level?: HostDefaultsLevel;
|
|
14
|
+
/** A host's own value, or a value set at the level being edited. */
|
|
15
|
+
isOwn: (fullKey: string) => boolean;
|
|
16
|
+
/** Where the value it would otherwise have comes from. */
|
|
17
|
+
source: (fullKey: string) => HostDefaultSource | undefined;
|
|
18
|
+
/** Follows the default again, or clears the value at this level. */
|
|
19
|
+
reset: (fullKey: string) => void;
|
|
20
|
+
/** Whether the key can have a default here at all. */
|
|
21
|
+
isAvailable: (fullKey: string) => boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare const HostDefaultsContext: import("react").Context<HostDefaultsContextValue>;
|
|
24
|
+
export declare function useHostDefaults(): HostDefaultsContextValue | null;
|
|
25
|
+
/** Whether the editor is editing a level of defaults rather than a host. */
|
|
26
|
+
export declare function useIsDefaultsEditor(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* A short key ("fontSize") is the calling plugin's own; core passes a full
|
|
29
|
+
* one ("core.sshPort").
|
|
30
|
+
*/
|
|
31
|
+
export declare function useDefaultKey(settingKey: string | undefined): string | null;
|
|
32
|
+
export declare function useSourceLabel(): (source: HostDefaultSource | undefined) => string;
|
|
33
|
+
/**
|
|
34
|
+
* The marker next to a field's label: where an inherited value comes from,
|
|
35
|
+
* or a control to hand an own value back.
|
|
36
|
+
*/
|
|
37
|
+
export declare function HostDefaultBadge({ settingKey }: {
|
|
38
|
+
settingKey: string;
|
|
39
|
+
}): import("react").JSX.Element;
|
|
40
|
+
/** Renders its children only when the key can have a default in this editor. */
|
|
41
|
+
export declare function DefaultsOnly({ settingKey, children, }: {
|
|
42
|
+
settingKey: string;
|
|
43
|
+
children: React.ReactNode;
|
|
44
|
+
}): import("react").JSX.Element;
|
|
45
|
+
/** Renders its children only when editing a host, never a level of defaults. */
|
|
46
|
+
export declare function HostOnly({ children }: {
|
|
47
|
+
children: React.ReactNode;
|
|
48
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SSHHost, SSHFolder } from "../../types/index";
|
|
2
|
+
import type { ServerStatus } from "../main-axios";
|
|
3
|
+
export declare function getCachedSSHHosts(loader: () => Promise<SSHHost[]>): Promise<SSHHost[]>;
|
|
4
|
+
export declare function getCachedServerStatuses(loader: () => Promise<Record<number, ServerStatus>>): Promise<Record<number, ServerStatus>>;
|
|
5
|
+
export declare function invalidateServerStatusCache(): void;
|
|
6
|
+
export declare function getCachedSSHFolders(loader: () => Promise<SSHFolder[]>): Promise<SSHFolder[]>;
|
|
7
|
+
export declare function invalidateSSHFoldersCache(): void;
|
|
8
|
+
/** Drop all caches after host mutations so the next read is fresh. */
|
|
9
|
+
export declare function invalidateHostsAndStatusCaches(): void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CustomKeybinding, KeyCombo } from "../../types/keybindings";
|
|
2
|
+
export declare function eventMatchesCombo(e: KeyboardEvent, combo: KeyCombo): boolean;
|
|
3
|
+
export declare function findMatchingKeybinding(e: KeyboardEvent, bindings: CustomKeybinding[]): CustomKeybinding | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SYNC_CHANGED_EVENT } from "./sync-events";
|
|
2
|
+
export { SYNC_CHANGED_EVENT };
|
|
3
|
+
/** The server this desktop is linked to, and the session it syncs with. */
|
|
4
|
+
export interface LinkedSession {
|
|
5
|
+
serverUrl: string;
|
|
6
|
+
token: string;
|
|
7
|
+
}
|
|
8
|
+
/** Null on the web, or when this desktop is not linked or signed out. */
|
|
9
|
+
export declare function getLinkedSession(): Promise<LinkedSession | null>;
|
|
10
|
+
export declare function notifySyncChanged(): void;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const LOCAL_ADAPTIVE_ENGINE_KEY = "termix.local.adaptive-engine.v1";
|
|
2
|
+
export interface LocalAdaptiveOutcome {
|
|
3
|
+
success?: boolean;
|
|
4
|
+
latencyMs?: number;
|
|
5
|
+
cancelled?: boolean;
|
|
6
|
+
fallback?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface LocalAdaptiveActionStats {
|
|
9
|
+
weight: number;
|
|
10
|
+
updatedAt: number;
|
|
11
|
+
observations: number;
|
|
12
|
+
successes: number;
|
|
13
|
+
cancellations: number;
|
|
14
|
+
fallbacks: number;
|
|
15
|
+
latencyEwmaMs?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface LocalAdaptiveDecision<T extends string> {
|
|
18
|
+
action: T;
|
|
19
|
+
confidence: number;
|
|
20
|
+
reason: "fallback" | "insufficient-evidence" | "learned";
|
|
21
|
+
expiresAt: number;
|
|
22
|
+
}
|
|
23
|
+
interface DecisionOptions<T extends string> {
|
|
24
|
+
scope: string;
|
|
25
|
+
candidates: readonly T[];
|
|
26
|
+
fallback: T;
|
|
27
|
+
now?: number;
|
|
28
|
+
ttlMs?: number;
|
|
29
|
+
minEvidence?: number;
|
|
30
|
+
minShare?: number;
|
|
31
|
+
minMargin?: number;
|
|
32
|
+
}
|
|
33
|
+
/** Records an abstract user choice. Never pass raw paths, input, or content. */
|
|
34
|
+
export declare function recordLocalAdaptiveChoice(scope: string, action: string, now?: number): void;
|
|
35
|
+
/** Records performance separately so failed actions are not reinforced. */
|
|
36
|
+
export declare function recordLocalAdaptiveOutcome(scope: string, action: string, outcome: LocalAdaptiveOutcome, now?: number): void;
|
|
37
|
+
export declare function chooseLocalAdaptiveAction<T extends string>({ scope, candidates, fallback, now, ttlMs, minEvidence, minShare, minMargin, }: DecisionOptions<T>): LocalAdaptiveDecision<T>;
|
|
38
|
+
export declare function getLocalAdaptiveStats(scope: string): Readonly<Record<string, LocalAdaptiveActionStats>>;
|
|
39
|
+
export declare function clearLocalAdaptiveEngine(): void;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend copy of the permission matching rules.
|
|
3
|
+
*
|
|
4
|
+
* This mirrors PermissionManager.hasPermission in
|
|
5
|
+
* src/backend/utils/permission-manager.ts and has to stay in step with it. It
|
|
6
|
+
* is a second implementation of one rule, which is a real cost, accepted here
|
|
7
|
+
* only because this copy is cosmetic: it decides what UI to show, never what
|
|
8
|
+
* a request is allowed to do. The server checks again on every route.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Whether a granted permission set covers the one required.
|
|
12
|
+
*
|
|
13
|
+
* Order matches the backend: the "*" superuser grant, an exact match, then
|
|
14
|
+
* progressively shorter dotted wildcards, then admin last.
|
|
15
|
+
*/
|
|
16
|
+
export declare function matchesPermission(granted: readonly string[], isAdmin: boolean, required: string): boolean;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a plugin's i18n keys resolve from.
|
|
3
|
+
*
|
|
4
|
+
* A manifest writes plugin-relative keys ("permissions.devices.view.title") so
|
|
5
|
+
* it never has to know where the strings live. They live in the plugin's own
|
|
6
|
+
* locales/en.json, loaded into an i18next namespace named after the plugin,
|
|
7
|
+
* so the qualified key is "<pluginId>:<key>". A key that already names a
|
|
8
|
+
* namespace is left alone. Missing keys fall back to core strings.
|
|
9
|
+
*/
|
|
10
|
+
export declare function pluginKey(pluginId: string, key: string): string;
|
|
11
|
+
export declare function pluginKey(pluginId: string, key: string | undefined): string | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type LucideProps } from "lucide-react";
|
|
2
|
+
/**
|
|
3
|
+
* A manifest names its icon as a Lucide component name ("Sparkles").
|
|
4
|
+
*
|
|
5
|
+
* An unknown or missing name falls back to a generic plugin glyph rather than
|
|
6
|
+
* rendering nothing, so a plugin shipping a typo still gets a row an admin can
|
|
7
|
+
* read.
|
|
8
|
+
*/
|
|
9
|
+
export declare function PluginIcon({ name, ...props }: {
|
|
10
|
+
name?: string;
|
|
11
|
+
} & LucideProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a plugin frontend reaches its own backend.
|
|
3
|
+
*
|
|
4
|
+
* Every plugin serves HTTP under /plugin-api/<id>/ and WebSockets under
|
|
5
|
+
* /plugin-ws/<id>/<path> on the main backend. No plugin has a port of its own,
|
|
6
|
+
* so these two helpers are all a plugin frontend needs, in every deployment:
|
|
7
|
+
*
|
|
8
|
+
* - web, same origin, optionally under a base path;
|
|
9
|
+
* - Docker behind nginx, which proxies both prefixes;
|
|
10
|
+
* - the Vite dev server, which proxies through /__termix_api/30001;
|
|
11
|
+
* - Electron with its embedded local backend;
|
|
12
|
+
* - Electron pointed at a remote Termix server, for hosts whose connection
|
|
13
|
+
* origin resolves there.
|
|
14
|
+
*
|
|
15
|
+
* A7 re-exports both through @termix-ssh/plugin-sdk/frontend. They live here for
|
|
16
|
+
* now because plugin frontends are still bundled with the shell.
|
|
17
|
+
*/
|
|
18
|
+
import type { AxiosInstance } from "axios";
|
|
19
|
+
import { type ConnectionOrigin, type WebSocketConnectionTarget } from "./connection-origin";
|
|
20
|
+
/**
|
|
21
|
+
* An axios client rooted at this plugin's /plugin-api mount point.
|
|
22
|
+
*
|
|
23
|
+
* Built on the shared authenticated instance, so a plugin inherits the same
|
|
24
|
+
* interceptors as core: auth headers, session expiry handling and error
|
|
25
|
+
* reporting all behave identically.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createPluginApi(pluginId: string): AxiosInstance;
|
|
28
|
+
/**
|
|
29
|
+
* A raw fetch on this plugin's /plugin-api mount point, for a response the
|
|
30
|
+
* caller reads as a stream (server-sent events). axios buffers the whole
|
|
31
|
+
* body, so it cannot. Sends the same auth the shared client does.
|
|
32
|
+
*/
|
|
33
|
+
export declare function pluginFetch(pluginId: string, path: string, init?: RequestInit): Promise<Response>;
|
|
34
|
+
/**
|
|
35
|
+
* The same client pointed at the connected remote server, for a desktop app
|
|
36
|
+
* host whose connection origin is "remote". Outside Electron, and for
|
|
37
|
+
* "local", it is the ordinary client.
|
|
38
|
+
*/
|
|
39
|
+
export declare function pluginApiFor(pluginId: string, origin: ConnectionOrigin | undefined, local: AxiosInstance): AxiosInstance;
|
|
40
|
+
/**
|
|
41
|
+
* The WebSocket URL for /plugin-ws/<id>/<path>, plus the subprotocols that
|
|
42
|
+
* carry the JWT.
|
|
43
|
+
*
|
|
44
|
+
* In Electron the right backend depends on where the host actually lives, so
|
|
45
|
+
* pass the resolved origin; without one it targets the embedded local backend,
|
|
46
|
+
* which is what a plugin with no per-host notion of origin wants.
|
|
47
|
+
*/
|
|
48
|
+
export declare function pluginWsUrl(pluginId: string, path: string, options?: {
|
|
49
|
+
origin?: ConnectionOrigin;
|
|
50
|
+
}): Promise<WebSocketConnectionTarget | null>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A keyed, reactive list of contributions.
|
|
3
|
+
*
|
|
4
|
+
* Plugins register and unregister at runtime, so anything the shell renders
|
|
5
|
+
* from a registry has to re-render when it changes. The snapshot array is
|
|
6
|
+
* cached until the next change because useSyncExternalStore compares by
|
|
7
|
+
* identity and loops forever on a fresh array.
|
|
8
|
+
*/
|
|
9
|
+
export interface Registry<T extends {
|
|
10
|
+
id: string;
|
|
11
|
+
}> {
|
|
12
|
+
/** Adds or replaces by id. The disposer only removes this exact entry. */
|
|
13
|
+
register: (item: T) => () => void;
|
|
14
|
+
unregister: (id: string) => void;
|
|
15
|
+
get: (id: string) => T | undefined;
|
|
16
|
+
list: () => T[];
|
|
17
|
+
subscribe: (listener: () => void) => () => void;
|
|
18
|
+
/** React hook over list(). */
|
|
19
|
+
useList: () => T[];
|
|
20
|
+
reset: () => void;
|
|
21
|
+
}
|
|
22
|
+
export declare function createRegistry<T extends {
|
|
23
|
+
id: string;
|
|
24
|
+
}>(sort?: (a: T, b: T) => number): Registry<T>;
|
|
25
|
+
/** Orders by `order`, then id, so plugin contributions sort stably. */
|
|
26
|
+
export declare function byOrderThenId<T extends {
|
|
27
|
+
id: string;
|
|
28
|
+
order?: number;
|
|
29
|
+
}>(a: T, b: T): number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A length in px at the Normal interface size, as rem, so it follows the
|
|
3
|
+
* interface size setting like Tailwind classes do.
|
|
4
|
+
*/
|
|
5
|
+
export declare function rem(px: number): string;
|
|
6
|
+
/** How many real pixels one Normal-size pixel takes right now. */
|
|
7
|
+
export declare function remScale(): number;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AxiosInstance } from "axios";
|
|
2
|
+
/**
|
|
3
|
+
* Hosts shared with a linked account arrive through sync as read-only local
|
|
4
|
+
* copies that already carry the auth the owner shared, so a connection needs
|
|
5
|
+
* nothing extra. Kept for plugins that still call it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function hydrateLocalSharedHostAuth<T>(host: T): Promise<T>;
|
|
8
|
+
/** The linked server's core API, or null when this desktop is not linked. */
|
|
9
|
+
export declare function getConnectedRemoteApi(): Promise<AxiosInstance | null>;
|
|
10
|
+
/** The linked server's own id for a host, found by its sync id. */
|
|
11
|
+
export declare function resolveRemoteHostId(syncId: string | null | undefined): Promise<number | null>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type StatusValue = "online" | "offline" | "unknown";
|
|
2
|
+
export interface ServerStatusEntry {
|
|
3
|
+
status: "online" | "offline";
|
|
4
|
+
lastChecked: string;
|
|
5
|
+
}
|
|
6
|
+
type Listener = () => void;
|
|
7
|
+
/**
|
|
8
|
+
* Mutable store for per-host status so list rows can subscribe to a single host
|
|
9
|
+
* via useSyncExternalStore instead of re-rendering the whole tree on every poll.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ServerStatusStore {
|
|
12
|
+
private statuses;
|
|
13
|
+
private initialLoadComplete;
|
|
14
|
+
private readonly hostListeners;
|
|
15
|
+
private readonly allListeners;
|
|
16
|
+
private readonly metaListeners;
|
|
17
|
+
/** "unknown" until the host has been checked. */
|
|
18
|
+
getStatus(hostId: number): StatusValue;
|
|
19
|
+
getStatuses(): Map<number, ServerStatusEntry>;
|
|
20
|
+
getInitialLoadComplete(): boolean;
|
|
21
|
+
getMetaSnapshot(): string;
|
|
22
|
+
subscribeHost(hostId: number, listener: Listener): () => void;
|
|
23
|
+
subscribeAll(listener: Listener): () => void;
|
|
24
|
+
subscribeMeta(listener: Listener): () => void;
|
|
25
|
+
setInitialLoadComplete(complete: boolean): void;
|
|
26
|
+
/**
|
|
27
|
+
* Replace status map. Notifies only hosts whose status value changed,
|
|
28
|
+
* plus allListeners when any change occurred.
|
|
29
|
+
*/
|
|
30
|
+
applyStatuses(next: Map<number, ServerStatusEntry>): void;
|
|
31
|
+
/** Forgets everything, on sign out. */
|
|
32
|
+
clear(): void;
|
|
33
|
+
private emitHost;
|
|
34
|
+
private emitAll;
|
|
35
|
+
private emitMeta;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type SyncStatus } from "../api/sync-api";
|
|
2
|
+
export declare function subscribeSyncStatus(listener: () => void): () => void;
|
|
3
|
+
export declare function getSyncStatusSnapshot(): SyncStatus | null;
|
|
4
|
+
/** Takes a status a request already returned, and checks again soon. */
|
|
5
|
+
export declare function setSyncStatus(next: SyncStatus): void;
|
|
6
|
+
export declare function refreshSyncStatus(): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { DashboardCardConfig, FontSizeId, UiFontId } from "../../types/ui-types";
|
|
2
|
+
export declare const DASHBOARD_CARDS: DashboardCardConfig[];
|
|
3
|
+
export declare const ACCENT_PRESET_COLORS: {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
}[];
|
|
7
|
+
export declare function applyAccentColor(colorValue: string): void;
|
|
8
|
+
export declare const FONT_SIZES: {
|
|
9
|
+
id: FontSizeId;
|
|
10
|
+
label: string;
|
|
11
|
+
}[];
|
|
12
|
+
/** The root font size of each interface size, relative to Normal. */
|
|
13
|
+
export declare const FONT_SIZE_SCALE: Record<FontSizeId, number>;
|
|
14
|
+
export declare function applyFontSize(id: FontSizeId): void;
|
|
15
|
+
export declare const UI_FONTS: {
|
|
16
|
+
id: UiFontId;
|
|
17
|
+
label: string;
|
|
18
|
+
family: string;
|
|
19
|
+
}[];
|
|
20
|
+
export declare function applyUiFont(id: UiFontId): void;
|
|
21
|
+
export declare const FOLDER_COLORS: string[];
|