@termix-ssh/plugin-sdk 1.0.13 → 1.0.17
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/CHANGELOG.md +49 -0
- package/PLUGIN-GUIDE.md +104 -69
- package/dist/backend.d.ts +500 -1
- package/dist/backend.js +7 -0
- package/dist/capabilities.js +4 -0
- package/dist/frontend.d.ts +45 -0
- package/dist/host/{PluginsTab-OXQQ7M4I.js → PluginsTab-YAGYRBIE.js} +3 -3
- package/dist/host/{chunk-T2PZWXFJ.js → chunk-2MU6WNSX.js} +1 -1
- package/dist/host/{chunk-54KCK6IZ.js → chunk-446UEDSK.js} +6 -2
- package/dist/host/{chunk-CN5UBTBP.js → chunk-7LEJ3HYF.js} +49 -3
- package/dist/host/{chunk-CALNJCHN.js → chunk-J2AILBXM.js} +561 -400
- package/dist/host/{chunk-ERGN4YW6.js → chunk-LQKK2JJA.js} +5 -1
- package/dist/host/core-classes.json +1 -1
- package/dist/host/{linked-server-5VFO4XQB.js → linked-server-OUF3POT7.js} +5 -3
- package/dist/host/{rbac-api-5YMBJAO5.js → rbac-api-LZVENREG.js} +1 -1
- package/dist/host/testing-host.js +4 -4
- package/dist/host/types/src/types/index.d.ts +10 -0
- package/dist/host/types/src/types/onboarding.d.ts +0 -1
- package/dist/host/types/src/types/ui-types.d.ts +3 -1
- package/dist/host/types/src/ui/api/auth-methods-api.d.ts +2 -0
- package/dist/host/types/src/ui/api/settings-api.d.ts +6 -0
- package/dist/host/types/src/ui/api/ssh-host-management-api.d.ts +6 -0
- package/dist/host/types/src/ui/auth/Auth.d.ts +1 -0
- package/dist/host/types/src/ui/lib/linked-server.d.ts +2 -0
- package/dist/host/types/src/ui/main-axios.d.ts +2 -2
- package/dist/host/types/src/ui/plugin-host/NativeView.d.ts +19 -0
- package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +4 -8
- package/dist/host/types/src/ui/shell/CompanionFrame.d.ts +11 -0
- package/dist/host/types/src/ui/shell/companions.d.ts +63 -0
- package/dist/host/types/src/ui/sidebar/AuthEnrollmentSections.d.ts +4 -1
- package/dist/host/ui.js +171 -820
- package/dist/host/{use-permissions-ISEDRY3J.js → use-permissions-BYCDS5PD.js} +1 -1
- package/dist/manifest.d.ts +1 -1
- package/dist/manifest.js +1 -1
- package/dist/testing.d.ts +26 -2
- package/dist/testing.js +89 -1
- package/dist/vitest-preset.js +23 -0
- package/package.json +1 -1
- package/schema/manifest.schema.json +4 -0
- package/dist/host/types/src/ui/api/sync-api.d.ts +0 -93
- package/dist/host/types/src/ui/auth/ElectronLoginForm.d.ts +0 -9
- package/dist/host/types/src/ui/hooks/use-sync-status.d.ts +0 -4
- package/dist/host/types/src/ui/lib/sync-status.d.ts +0 -6
- package/dist/host/types/src/ui/settings/sync/LinkServerDialog.d.ts +0 -12
- package/dist/host/types/src/ui/settings/sync/ProxySettingsFields.d.ts +0 -15
- package/dist/host/types/src/ui/settings/sync/saved-servers.d.ts +0 -3
|
@@ -3,14 +3,16 @@ import {
|
|
|
3
3
|
hasPermission,
|
|
4
4
|
resetPermissionsCache,
|
|
5
5
|
usePermissions
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2MU6WNSX.js";
|
|
7
7
|
import {
|
|
8
|
+
ArrowDownToLine,
|
|
9
|
+
ArrowLeftToLine,
|
|
10
|
+
ArrowRightToLine,
|
|
8
11
|
Button,
|
|
9
12
|
Check,
|
|
10
13
|
Checkbox,
|
|
11
14
|
CheckboxIndicator,
|
|
12
15
|
CircleSlash,
|
|
13
|
-
Cloud,
|
|
14
16
|
Columns2,
|
|
15
17
|
DefaultsOnly,
|
|
16
18
|
DocsLink,
|
|
@@ -27,6 +29,7 @@ import {
|
|
|
27
29
|
OPEN_PLUGIN_SETTINGS_EVENT,
|
|
28
30
|
PLUGINS_CHANGED_EVENT,
|
|
29
31
|
PLUGIN_SETTINGS_CHANGED_EVENT,
|
|
32
|
+
PanelRight,
|
|
30
33
|
Plug,
|
|
31
34
|
PluginIcon,
|
|
32
35
|
Puzzle,
|
|
@@ -80,7 +83,7 @@ import {
|
|
|
80
83
|
withIconBoundary,
|
|
81
84
|
withPluginContext,
|
|
82
85
|
withPluginScope
|
|
83
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-LQKK2JJA.js";
|
|
84
87
|
import {
|
|
85
88
|
SYNC_CHANGED_EVENT,
|
|
86
89
|
TRUST_TOKEN_KEY,
|
|
@@ -118,7 +121,6 @@ import {
|
|
|
118
121
|
logActivity,
|
|
119
122
|
manifestDeclares,
|
|
120
123
|
markUserAuthenticated,
|
|
121
|
-
notifySyncChanged,
|
|
122
124
|
parseCustomKeybindings,
|
|
123
125
|
patchOpenTab,
|
|
124
126
|
pluginStepKey,
|
|
@@ -130,7 +132,7 @@ import {
|
|
|
130
132
|
usePluginStore,
|
|
131
133
|
useTabTypes,
|
|
132
134
|
websocketAuthProtocols
|
|
133
|
-
} from "./chunk-
|
|
135
|
+
} from "./chunk-7LEJ3HYF.js";
|
|
134
136
|
import {
|
|
135
137
|
define_import_meta_env_default,
|
|
136
138
|
init_define_import_meta_env
|
|
@@ -268,6 +270,14 @@ async function getLoginMethods() {
|
|
|
268
270
|
return [];
|
|
269
271
|
}
|
|
270
272
|
}
|
|
273
|
+
async function getRememberDeviceAllowed() {
|
|
274
|
+
try {
|
|
275
|
+
const response = await authApi.get("/users/auth/methods");
|
|
276
|
+
return response.data?.rememberDevice !== false;
|
|
277
|
+
} catch {
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
271
281
|
async function submitLoginMethod(methodId, body, instanceId) {
|
|
272
282
|
try {
|
|
273
283
|
const response = await authApi.post(
|
|
@@ -1114,13 +1124,6 @@ var en_default = {
|
|
|
1114
1124
|
pluginsLoadFailed: "The plugin list could not be loaded. You can choose plugins later from the Plugins tab.",
|
|
1115
1125
|
securityTitle: "Secure your account",
|
|
1116
1126
|
securityIntro: "Add a passkey or an authenticator app to your account. You can also do this later in Settings, under Security.",
|
|
1117
|
-
desktopTitle: "How do you want to use Termix?",
|
|
1118
|
-
desktopBody: "You can change this any time from Sync in the sidebar.",
|
|
1119
|
-
desktopLocalTitle: "On this device only",
|
|
1120
|
-
desktopLocalBody: "Everything is stored here. Nothing to set up.",
|
|
1121
|
-
desktopLinkTitle: "With my Termix server",
|
|
1122
|
-
desktopLinkBody: "Sign in to your server to use the same hosts and settings on every device.",
|
|
1123
|
-
desktopLinked: "Linked to {{server}}",
|
|
1124
1127
|
pluginsDocsLink: "Read about each one"
|
|
1125
1128
|
},
|
|
1126
1129
|
desktopUpdates: {
|
|
@@ -1141,6 +1144,11 @@ var en_default = {
|
|
|
1141
1144
|
ready: "Termix {{version}} is ready to install",
|
|
1142
1145
|
readyHint: "It installs the next time Termix restarts."
|
|
1143
1146
|
},
|
|
1147
|
+
companion: {
|
|
1148
|
+
close: "Close panel",
|
|
1149
|
+
moveSide: "Move panel",
|
|
1150
|
+
resize: "Resize panel"
|
|
1151
|
+
},
|
|
1144
1152
|
nav: {
|
|
1145
1153
|
home: "Home",
|
|
1146
1154
|
terminal: "Terminal",
|
|
@@ -1151,7 +1159,6 @@ var en_default = {
|
|
|
1151
1159
|
hosts: "Hosts",
|
|
1152
1160
|
credentials: "Credentials",
|
|
1153
1161
|
connections: "Connections",
|
|
1154
|
-
sync: "Sync",
|
|
1155
1162
|
reconnectDisconnectedTerminals: "Reconnect all disconnected terminals",
|
|
1156
1163
|
reconnectingTerminals_one: "Reconnecting {{count}} terminal",
|
|
1157
1164
|
reconnectingTerminals_other: "Reconnecting {{count}} terminals",
|
|
@@ -1447,6 +1454,9 @@ var en_default = {
|
|
|
1447
1454
|
deleteFolderConfirm_one: 'Delete "{{name}}" and its {{count}} host? This cannot be undone.',
|
|
1448
1455
|
deleteFolderConfirm_other: 'Delete "{{name}}" and its {{count}} hosts? This cannot be undone.',
|
|
1449
1456
|
failedToMoveHosts: "Failed to move hosts",
|
|
1457
|
+
managedBanner: "This host is managed by {{plugin}}. Change it there. You can still pin and reorder it.",
|
|
1458
|
+
managedTooltip: "Managed by {{plugin}}",
|
|
1459
|
+
addBlocked: "Hosts are managed by {{plugin}}, so new hosts can't be added here.",
|
|
1450
1460
|
failedToReorder: "Failed to reorder",
|
|
1451
1461
|
expandAll: "Expand all folders",
|
|
1452
1462
|
collapseAll: "Collapse all folders",
|
|
@@ -2043,6 +2053,18 @@ var en_default = {
|
|
|
2043
2053
|
title: "Handle sign in",
|
|
2044
2054
|
consequence: "It can add a login method, a second factor or an SSH sign-in type."
|
|
2045
2055
|
},
|
|
2056
|
+
"auth:policy": {
|
|
2057
|
+
title: "Set sign in rules",
|
|
2058
|
+
consequence: "It can sign people out when idle, limit session length, turn off remember me and require a second factor."
|
|
2059
|
+
},
|
|
2060
|
+
"ssh:transport": {
|
|
2061
|
+
title: "Choose how hosts are reached",
|
|
2062
|
+
consequence: "It can carry the SSH connection to a host over its own route, so it sees everything sent to and from those hosts, passwords included."
|
|
2063
|
+
},
|
|
2064
|
+
"sync:provide": {
|
|
2065
|
+
title: "Run sync",
|
|
2066
|
+
consequence: "It can answer all sync requests, so it sees the data that devices and servers sync."
|
|
2067
|
+
},
|
|
2046
2068
|
"system:tls": {
|
|
2047
2069
|
title: "Manage certificates",
|
|
2048
2070
|
consequence: "It can replace the certificate Termix serves over HTTPS and answer domain checks from certificate authorities."
|
|
@@ -2111,6 +2133,10 @@ var en_default = {
|
|
|
2111
2133
|
title: "Store recent activity",
|
|
2112
2134
|
consequence: "Becomes the store for the recent activity list of every user."
|
|
2113
2135
|
},
|
|
2136
|
+
"hosts:lock": {
|
|
2137
|
+
title: "Manage hosts as read only",
|
|
2138
|
+
consequence: "Hosts it manages can't be edited, deleted or reshared by anyone else."
|
|
2139
|
+
},
|
|
2114
2140
|
"desktop:window": {
|
|
2115
2141
|
title: "Open desktop windows",
|
|
2116
2142
|
consequence: "Only in the Termix desktop app."
|
|
@@ -2507,87 +2533,6 @@ var en_default = {
|
|
|
2507
2533
|
noData: "No data",
|
|
2508
2534
|
filter: "Filter..."
|
|
2509
2535
|
},
|
|
2510
|
-
sync: {
|
|
2511
|
-
minutesAgo_one: "{{count}} minute ago",
|
|
2512
|
-
minutesAgo_other: "{{count}} minutes ago",
|
|
2513
|
-
hoursAgo_one: "{{count}} hour ago",
|
|
2514
|
-
hoursAgo_other: "{{count}} hours ago",
|
|
2515
|
-
pending_one: "{{count}} change waiting to sync",
|
|
2516
|
-
pending_other: "{{count}} changes waiting to sync",
|
|
2517
|
-
proxy: {
|
|
2518
|
-
headersTitle: "Extra headers",
|
|
2519
|
-
headersHint: "Sent with every request to the server, for example a Cloudflare Access service token.",
|
|
2520
|
-
headerName: "Header name",
|
|
2521
|
-
headerValue: "Value",
|
|
2522
|
-
savedValue: "Saved, type to change",
|
|
2523
|
-
addHeader: "Add header",
|
|
2524
|
-
removeHeader: "Remove header",
|
|
2525
|
-
basicAuthTitle: "Username and password",
|
|
2526
|
-
basicAuthHint: "For a proxy that asks for a username and password before Termix.",
|
|
2527
|
-
username: "Username",
|
|
2528
|
-
password: "Password",
|
|
2529
|
-
allowInvalidCertificate: "Trust a self-signed certificate",
|
|
2530
|
-
allowInvalidCertificateHint: "Only for your own server, when its certificate is not from a known authority."
|
|
2531
|
-
},
|
|
2532
|
-
problems: {
|
|
2533
|
-
invalidUrl: "That does not look like a web address.",
|
|
2534
|
-
unreachable: "Could not reach the server. Check the address and that the server is running.",
|
|
2535
|
-
unreachableWithReason: "Could not reach the server: {{reason}}",
|
|
2536
|
-
tlsUntrusted: "The server certificate is not trusted. If this is your own server with a self-signed certificate, turn on the option below.",
|
|
2537
|
-
basicAuthRequired: "Something in front of the server asks for a username and password. Enter them below.",
|
|
2538
|
-
proxyLogin: "A login page or proxy answered instead of Termix. Add the headers it needs below, or check the address.",
|
|
2539
|
-
notTermix: "There is no Termix server at that address. If it runs under a path, include it, like https://example.com/termix.",
|
|
2540
|
-
versionMismatch: "That server runs an older Termix. Update it to 2.9 or newer to link.",
|
|
2541
|
-
differentAccount: "You signed in to a different account. Sign in to the account this device is linked to, or unlink first."
|
|
2542
|
-
},
|
|
2543
|
-
wizard: {
|
|
2544
|
-
title: "Link to a Termix server",
|
|
2545
|
-
reloginTitle: "Sign in again",
|
|
2546
|
-
savedServers: "Recent servers",
|
|
2547
|
-
removeServer: "Remove from the list",
|
|
2548
|
-
serverDescription: "Enter the address you use to open Termix in your browser.",
|
|
2549
|
-
signinDescription: "Sign in to {{url}}",
|
|
2550
|
-
chooseDescription: "This device already has data. What should happen to it?",
|
|
2551
|
-
finishingDescription: "Linking this device.",
|
|
2552
|
-
serverUrl: "Server address",
|
|
2553
|
-
serverUrlHint: "For example https://termix.example.com",
|
|
2554
|
-
showProxySettings: "Reverse proxy settings",
|
|
2555
|
-
hideProxySettings: "Hide reverse proxy settings",
|
|
2556
|
-
continue: "Continue",
|
|
2557
|
-
back: "Back",
|
|
2558
|
-
mergeTitle: "Add it to my account",
|
|
2559
|
-
mergeBody_one: "The item on this device is added to your account. Items your account already has stay as they are on the server.",
|
|
2560
|
-
mergeBody_other: "The {{count}} items on this device are added to your account. Items your account already has stay as they are on the server.",
|
|
2561
|
-
replaceTitle: "Replace it with my account",
|
|
2562
|
-
replaceBody_one: "The item on this device is removed, and this device takes everything from your account. Hosts kept on this device only stay.",
|
|
2563
|
-
replaceBody_other: "The {{count}} items on this device are removed, and this device takes everything from your account. Hosts kept on this device only stay.",
|
|
2564
|
-
link: "Link",
|
|
2565
|
-
linking: "Linking and running the first sync...",
|
|
2566
|
-
linked: "Linked. Your data is syncing now.",
|
|
2567
|
-
signedInAgain: "Signed in. Sync is running again."
|
|
2568
|
-
},
|
|
2569
|
-
entities: {
|
|
2570
|
-
hosts: "Hosts",
|
|
2571
|
-
sshCredentials: "Credentials",
|
|
2572
|
-
sshFolders: "Folders",
|
|
2573
|
-
userPreferences: "Preferences",
|
|
2574
|
-
pluginUserSettings: "Plugin settings",
|
|
2575
|
-
sharedHosts: "Hosts shared with you",
|
|
2576
|
-
sharedCredentials: "Credentials shared with you",
|
|
2577
|
-
vaultProfiles: "Vault profiles",
|
|
2578
|
-
snippetFolders: "Snippet folders",
|
|
2579
|
-
snippets: "Snippets",
|
|
2580
|
-
dashboardServiceLinks: "Service links",
|
|
2581
|
-
homepageItems: "Homepage items",
|
|
2582
|
-
networkTopology: "Network map",
|
|
2583
|
-
workspaces: "Workspaces",
|
|
2584
|
-
hostDefaults: "Host defaults",
|
|
2585
|
-
hostDefaultsAdmin: "Server host defaults",
|
|
2586
|
-
aiProviders: "AI providers",
|
|
2587
|
-
homepageLayouts: "Homepage layouts",
|
|
2588
|
-
accountProfile: "Account profile"
|
|
2589
|
-
}
|
|
2590
|
-
},
|
|
2591
2536
|
hostDefaults: {
|
|
2592
2537
|
source: {
|
|
2593
2538
|
folder: "Folder {{name}}",
|
|
@@ -2648,8 +2593,8 @@ var localeLoaders = Object.fromEntries(
|
|
|
2648
2593
|
Object.entries(LOCALE_FILES).map(([code, file]) => [
|
|
2649
2594
|
code,
|
|
2650
2595
|
() => {
|
|
2651
|
-
const
|
|
2652
|
-
return
|
|
2596
|
+
const load2 = translatedFiles[`../locales/translated/${file}.json`];
|
|
2597
|
+
return load2 ? load2() : Promise.reject(new Error(`no ${file}`));
|
|
2653
2598
|
}
|
|
2654
2599
|
])
|
|
2655
2600
|
);
|
|
@@ -2752,130 +2697,6 @@ function consumeLoginLanguage() {
|
|
|
2752
2697
|
}
|
|
2753
2698
|
var i18n_default = i18n;
|
|
2754
2699
|
|
|
2755
|
-
// src/ui/api/sync-api.ts
|
|
2756
|
-
init_define_import_meta_env();
|
|
2757
|
-
async function getSyncStatus() {
|
|
2758
|
-
return (await authApi.get("/sync/link/status")).data;
|
|
2759
|
-
}
|
|
2760
|
-
async function probeServer(target) {
|
|
2761
|
-
return (await authApi.post("/sync/link/probe", target)).data;
|
|
2762
|
-
}
|
|
2763
|
-
async function getLinkPreview() {
|
|
2764
|
-
return (await authApi.get("/sync/link/preview")).data?.counts ?? {};
|
|
2765
|
-
}
|
|
2766
|
-
async function completeLink(input) {
|
|
2767
|
-
return (await authApi.post("/sync/link/complete", input)).data;
|
|
2768
|
-
}
|
|
2769
|
-
async function reloginLink(token) {
|
|
2770
|
-
return (await authApi.post("/sync/link/relogin", { token })).data;
|
|
2771
|
-
}
|
|
2772
|
-
async function unlinkServer(keepData) {
|
|
2773
|
-
return (await authApi.post("/sync/link/unlink", { keepData })).data;
|
|
2774
|
-
}
|
|
2775
|
-
async function syncNow() {
|
|
2776
|
-
return (await authApi.post("/sync/link/sync", {}, { timeout: 3e5 })).data;
|
|
2777
|
-
}
|
|
2778
|
-
async function updateSyncSettings(settings) {
|
|
2779
|
-
return (await authApi.put("/sync/link/settings", settings)).data;
|
|
2780
|
-
}
|
|
2781
|
-
async function getSyncConflicts() {
|
|
2782
|
-
return (await authApi.get("/sync/link/conflicts")).data?.conflicts ?? [];
|
|
2783
|
-
}
|
|
2784
|
-
async function settleSyncConflict(id, keep) {
|
|
2785
|
-
await authApi.post(`/sync/link/conflicts/${id}`, { keep });
|
|
2786
|
-
}
|
|
2787
|
-
async function getSyncErrors() {
|
|
2788
|
-
return (await authApi.get("/sync/link/errors")).data?.errors ?? [];
|
|
2789
|
-
}
|
|
2790
|
-
async function retrySyncErrors() {
|
|
2791
|
-
return (await authApi.post("/sync/link/errors/retry", {}, { timeout: 3e5 })).data;
|
|
2792
|
-
}
|
|
2793
|
-
|
|
2794
|
-
// src/ui/lib/sync-status.ts
|
|
2795
|
-
init_define_import_meta_env();
|
|
2796
|
-
var IDLE_MS = 15e3;
|
|
2797
|
-
var BUSY_MS = 2e3;
|
|
2798
|
-
var snapshot = null;
|
|
2799
|
-
var timer = null;
|
|
2800
|
-
var lastSyncAt;
|
|
2801
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
2802
|
-
function emit() {
|
|
2803
|
-
for (const listener of listeners) listener();
|
|
2804
|
-
}
|
|
2805
|
-
function announce() {
|
|
2806
|
-
notifySyncChanged();
|
|
2807
|
-
window.dispatchEvent(new CustomEvent("hosts:refresh"));
|
|
2808
|
-
window.dispatchEvent(new CustomEvent("termix:hosts-changed"));
|
|
2809
|
-
window.dispatchEvent(new CustomEvent("termix:credentials-changed"));
|
|
2810
|
-
window.dispatchEvent(new CustomEvent("termix:plugins-changed"));
|
|
2811
|
-
}
|
|
2812
|
-
async function poll() {
|
|
2813
|
-
timer = null;
|
|
2814
|
-
try {
|
|
2815
|
-
const next = await getSyncStatus();
|
|
2816
|
-
const syncedAt = next.lastSyncAt ?? null;
|
|
2817
|
-
if (lastSyncAt !== void 0 && syncedAt !== lastSyncAt) announce();
|
|
2818
|
-
if (snapshot && snapshot.linked !== next.linked) notifySyncChanged();
|
|
2819
|
-
lastSyncAt = syncedAt;
|
|
2820
|
-
snapshot = next;
|
|
2821
|
-
emit();
|
|
2822
|
-
} catch {
|
|
2823
|
-
}
|
|
2824
|
-
schedule();
|
|
2825
|
-
}
|
|
2826
|
-
function schedule(delay) {
|
|
2827
|
-
if (listeners.size === 0 || timer) return;
|
|
2828
|
-
const busy = snapshot?.status === "syncing" || !!snapshot?.pending;
|
|
2829
|
-
timer = setTimeout(() => void poll(), delay ?? (busy ? BUSY_MS : IDLE_MS));
|
|
2830
|
-
}
|
|
2831
|
-
function subscribeSyncStatus(listener) {
|
|
2832
|
-
listeners.add(listener);
|
|
2833
|
-
if (isElectron() && listeners.size === 1 && !timer) void poll();
|
|
2834
|
-
return () => {
|
|
2835
|
-
listeners.delete(listener);
|
|
2836
|
-
if (listeners.size === 0 && timer) {
|
|
2837
|
-
clearTimeout(timer);
|
|
2838
|
-
timer = null;
|
|
2839
|
-
}
|
|
2840
|
-
};
|
|
2841
|
-
}
|
|
2842
|
-
function getSyncStatusSnapshot() {
|
|
2843
|
-
return snapshot;
|
|
2844
|
-
}
|
|
2845
|
-
function setSyncStatus(next) {
|
|
2846
|
-
snapshot = next;
|
|
2847
|
-
if (lastSyncAt !== void 0 && (next.lastSyncAt ?? null) !== lastSyncAt) {
|
|
2848
|
-
announce();
|
|
2849
|
-
}
|
|
2850
|
-
lastSyncAt = next.lastSyncAt ?? null;
|
|
2851
|
-
emit();
|
|
2852
|
-
if (timer) clearTimeout(timer);
|
|
2853
|
-
timer = null;
|
|
2854
|
-
schedule(BUSY_MS);
|
|
2855
|
-
}
|
|
2856
|
-
function refreshSyncStatus() {
|
|
2857
|
-
if (timer) clearTimeout(timer);
|
|
2858
|
-
timer = null;
|
|
2859
|
-
void poll();
|
|
2860
|
-
}
|
|
2861
|
-
|
|
2862
|
-
// src/ui/hooks/use-sync-status.ts
|
|
2863
|
-
init_define_import_meta_env();
|
|
2864
|
-
import { useSyncExternalStore } from "react";
|
|
2865
|
-
function useSyncStatus() {
|
|
2866
|
-
return useSyncExternalStore(
|
|
2867
|
-
subscribeSyncStatus,
|
|
2868
|
-
getSyncStatusSnapshot,
|
|
2869
|
-
() => null
|
|
2870
|
-
);
|
|
2871
|
-
}
|
|
2872
|
-
function useSyncAttentionCount() {
|
|
2873
|
-
const status = useSyncStatus();
|
|
2874
|
-
if (!status?.linked) return null;
|
|
2875
|
-
const count = (status.conflicts ?? 0) + (status.errors ?? 0) + (status.status === "signed_out" ? 1 : 0);
|
|
2876
|
-
return count || null;
|
|
2877
|
-
}
|
|
2878
|
-
|
|
2879
2700
|
// src/ui/shell/panel-registry.ts
|
|
2880
2701
|
init_define_import_meta_env();
|
|
2881
2702
|
var registry = createRegistry();
|
|
@@ -2887,7 +2708,7 @@ var resetPanels = registry.reset;
|
|
|
2887
2708
|
|
|
2888
2709
|
// src/ui/sidebar/rail-items.ts
|
|
2889
2710
|
init_define_import_meta_env();
|
|
2890
|
-
import { useMemo, useSyncExternalStore
|
|
2711
|
+
import { useMemo, useSyncExternalStore } from "react";
|
|
2891
2712
|
var RAIL_GROUP_ORDER = ["objects", "tools", "system"];
|
|
2892
2713
|
var RAIL_ITEMS = [
|
|
2893
2714
|
{
|
|
@@ -2920,15 +2741,6 @@ var RAIL_ITEMS = [
|
|
|
2920
2741
|
mobilePrimary: true,
|
|
2921
2742
|
group: "tools"
|
|
2922
2743
|
},
|
|
2923
|
-
{
|
|
2924
|
-
id: "sync",
|
|
2925
|
-
icon: Cloud,
|
|
2926
|
-
labelKey: "nav.sync",
|
|
2927
|
-
electronOnly: true,
|
|
2928
|
-
placement: "footer",
|
|
2929
|
-
group: "system",
|
|
2930
|
-
useBadge: useSyncAttentionCount
|
|
2931
|
-
},
|
|
2932
2744
|
{
|
|
2933
2745
|
id: "plugins",
|
|
2934
2746
|
icon: Puzzle,
|
|
@@ -2987,7 +2799,7 @@ function permittedRailItems(items, permissions) {
|
|
|
2987
2799
|
);
|
|
2988
2800
|
}
|
|
2989
2801
|
function useRailItems() {
|
|
2990
|
-
const items =
|
|
2802
|
+
const items = useSyncExternalStore(
|
|
2991
2803
|
registeredRailItems.subscribe,
|
|
2992
2804
|
railItemsSnapshot,
|
|
2993
2805
|
railItemsSnapshot
|
|
@@ -3352,12 +3164,12 @@ var resetDashboardCards = registry3.reset;
|
|
|
3352
3164
|
init_define_import_meta_env();
|
|
3353
3165
|
var points = /* @__PURE__ */ new Map();
|
|
3354
3166
|
function point(id) {
|
|
3355
|
-
let
|
|
3356
|
-
if (!
|
|
3357
|
-
|
|
3358
|
-
points.set(id,
|
|
3167
|
+
let registry6 = points.get(id);
|
|
3168
|
+
if (!registry6) {
|
|
3169
|
+
registry6 = createRegistry();
|
|
3170
|
+
points.set(id, registry6);
|
|
3359
3171
|
}
|
|
3360
|
-
return
|
|
3172
|
+
return registry6;
|
|
3361
3173
|
}
|
|
3362
3174
|
function registerExtension(pointId, extension) {
|
|
3363
3175
|
return point(pointId).register(extension);
|
|
@@ -3398,21 +3210,21 @@ init_define_import_meta_env();
|
|
|
3398
3210
|
var actions3 = /* @__PURE__ */ new Map();
|
|
3399
3211
|
var slots = /* @__PURE__ */ new Map();
|
|
3400
3212
|
var contributions = /* @__PURE__ */ new Map();
|
|
3401
|
-
var
|
|
3213
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
3402
3214
|
var snapshots = /* @__PURE__ */ new Map();
|
|
3403
3215
|
var EMPTY = [];
|
|
3404
|
-
function
|
|
3216
|
+
function emit() {
|
|
3405
3217
|
snapshots.clear();
|
|
3406
|
-
for (const listener of
|
|
3218
|
+
for (const listener of listeners) listener();
|
|
3407
3219
|
}
|
|
3408
3220
|
function registerAction(id, handler, options = {}) {
|
|
3409
3221
|
const action = { id, handler, ...options };
|
|
3410
3222
|
actions3.set(id, action);
|
|
3411
|
-
|
|
3223
|
+
emit();
|
|
3412
3224
|
return () => {
|
|
3413
3225
|
if (actions3.get(id) === action) {
|
|
3414
3226
|
actions3.delete(id);
|
|
3415
|
-
|
|
3227
|
+
emit();
|
|
3416
3228
|
}
|
|
3417
3229
|
};
|
|
3418
3230
|
}
|
|
@@ -3432,11 +3244,11 @@ async function invokeAction(id, ...args) {
|
|
|
3432
3244
|
}
|
|
3433
3245
|
function declareActionSlot(slot) {
|
|
3434
3246
|
slots.set(slot.id, slot);
|
|
3435
|
-
|
|
3247
|
+
emit();
|
|
3436
3248
|
return () => {
|
|
3437
3249
|
if (slots.get(slot.id) === slot) {
|
|
3438
3250
|
slots.delete(slot.id);
|
|
3439
|
-
|
|
3251
|
+
emit();
|
|
3440
3252
|
}
|
|
3441
3253
|
};
|
|
3442
3254
|
}
|
|
@@ -3457,7 +3269,7 @@ function registerSlotContribution(slotId, contribution) {
|
|
|
3457
3269
|
}
|
|
3458
3270
|
const stored = { ...contribution, kind };
|
|
3459
3271
|
forSlot.set(contribution.actionId, stored);
|
|
3460
|
-
|
|
3272
|
+
emit();
|
|
3461
3273
|
return () => {
|
|
3462
3274
|
if (contributions.get(slotId)?.get(contribution.actionId) === stored) {
|
|
3463
3275
|
unregisterSlotContribution(slotId, contribution.actionId);
|
|
@@ -3468,7 +3280,7 @@ function unregisterSlotContribution(slotId, actionId) {
|
|
|
3468
3280
|
const forSlot = contributions.get(slotId);
|
|
3469
3281
|
if (!forSlot?.delete(actionId)) return;
|
|
3470
3282
|
if (forSlot.size === 0) contributions.delete(slotId);
|
|
3471
|
-
|
|
3283
|
+
emit();
|
|
3472
3284
|
}
|
|
3473
3285
|
function getSlotContributions(slotId) {
|
|
3474
3286
|
const cached = snapshots.get(slotId);
|
|
@@ -3485,9 +3297,9 @@ function getSlotContributions(slotId) {
|
|
|
3485
3297
|
return sorted;
|
|
3486
3298
|
}
|
|
3487
3299
|
function subscribeToActionRegistry(listener) {
|
|
3488
|
-
|
|
3300
|
+
listeners.add(listener);
|
|
3489
3301
|
return () => {
|
|
3490
|
-
|
|
3302
|
+
listeners.delete(listener);
|
|
3491
3303
|
};
|
|
3492
3304
|
}
|
|
3493
3305
|
function resetActionRegistry() {
|
|
@@ -3495,7 +3307,7 @@ function resetActionRegistry() {
|
|
|
3495
3307
|
slots.clear();
|
|
3496
3308
|
contributions.clear();
|
|
3497
3309
|
snapshots.clear();
|
|
3498
|
-
|
|
3310
|
+
emit();
|
|
3499
3311
|
}
|
|
3500
3312
|
|
|
3501
3313
|
// src/ui/lib/plugin-transport.ts
|
|
@@ -3593,14 +3405,14 @@ async function pluginWsUrl(pluginId, path2, options = {}) {
|
|
|
3593
3405
|
init_define_import_meta_env();
|
|
3594
3406
|
import {
|
|
3595
3407
|
createElement,
|
|
3596
|
-
useSyncExternalStore as
|
|
3408
|
+
useSyncExternalStore as useSyncExternalStore2
|
|
3597
3409
|
} from "react";
|
|
3598
3410
|
var components = /* @__PURE__ */ new Map();
|
|
3599
|
-
var
|
|
3411
|
+
var listeners2 = /* @__PURE__ */ new Set();
|
|
3600
3412
|
var version = 0;
|
|
3601
3413
|
function notify() {
|
|
3602
3414
|
version += 1;
|
|
3603
|
-
for (const listener of
|
|
3415
|
+
for (const listener of listeners2) listener();
|
|
3604
3416
|
}
|
|
3605
3417
|
function registerPluginComponent(id, component) {
|
|
3606
3418
|
components.set(id, component);
|
|
@@ -3613,11 +3425,11 @@ function registerPluginComponent(id, component) {
|
|
|
3613
3425
|
};
|
|
3614
3426
|
}
|
|
3615
3427
|
function subscribe(listener) {
|
|
3616
|
-
|
|
3617
|
-
return () =>
|
|
3428
|
+
listeners2.add(listener);
|
|
3429
|
+
return () => listeners2.delete(listener);
|
|
3618
3430
|
}
|
|
3619
3431
|
function usePluginComponent(id) {
|
|
3620
|
-
|
|
3432
|
+
useSyncExternalStore2(subscribe, () => version);
|
|
3621
3433
|
return components.get(id);
|
|
3622
3434
|
}
|
|
3623
3435
|
function PluginComponent({
|
|
@@ -3711,7 +3523,7 @@ import { createContext, useContext, useEffect as useEffect3, useState as useStat
|
|
|
3711
3523
|
|
|
3712
3524
|
// src/ui/look/theme-registry.ts
|
|
3713
3525
|
init_define_import_meta_env();
|
|
3714
|
-
import { useSyncExternalStore as
|
|
3526
|
+
import { useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
3715
3527
|
var SYSTEM_THEME = "system";
|
|
3716
3528
|
var BUILTIN_THEMES = [
|
|
3717
3529
|
{
|
|
@@ -3730,23 +3542,23 @@ var BUILTIN_THEMES = [
|
|
|
3730
3542
|
var builtins = new Map(BUILTIN_THEMES.map((theme) => [theme.id, theme]));
|
|
3731
3543
|
var pluginThemes = /* @__PURE__ */ new Map();
|
|
3732
3544
|
var pluginThemesKnown = false;
|
|
3733
|
-
var
|
|
3734
|
-
var
|
|
3735
|
-
function
|
|
3736
|
-
|
|
3737
|
-
for (const listener of
|
|
3545
|
+
var listeners3 = /* @__PURE__ */ new Set();
|
|
3546
|
+
var snapshot = null;
|
|
3547
|
+
function emit2() {
|
|
3548
|
+
snapshot = null;
|
|
3549
|
+
for (const listener of listeners3) listener();
|
|
3738
3550
|
}
|
|
3739
3551
|
function listThemes() {
|
|
3740
|
-
if (!
|
|
3552
|
+
if (!snapshot) {
|
|
3741
3553
|
const replaced = BUILTIN_THEMES.map(
|
|
3742
3554
|
(theme) => pluginThemes.get(theme.id) ?? theme
|
|
3743
3555
|
);
|
|
3744
3556
|
const extra = [...pluginThemes.values()].filter(
|
|
3745
3557
|
(theme) => !builtins.has(theme.id)
|
|
3746
3558
|
);
|
|
3747
|
-
|
|
3559
|
+
snapshot = [...replaced, ...extra];
|
|
3748
3560
|
}
|
|
3749
|
-
return
|
|
3561
|
+
return snapshot;
|
|
3750
3562
|
}
|
|
3751
3563
|
function getTheme(id) {
|
|
3752
3564
|
return pluginThemes.get(id) ?? builtins.get(id);
|
|
@@ -3761,16 +3573,16 @@ function setPluginThemes(themes) {
|
|
|
3761
3573
|
});
|
|
3762
3574
|
if (same && !first) return;
|
|
3763
3575
|
pluginThemes = next;
|
|
3764
|
-
|
|
3576
|
+
emit2();
|
|
3765
3577
|
}
|
|
3766
3578
|
function subscribeThemes(listener) {
|
|
3767
|
-
|
|
3579
|
+
listeners3.add(listener);
|
|
3768
3580
|
return () => {
|
|
3769
|
-
|
|
3581
|
+
listeners3.delete(listener);
|
|
3770
3582
|
};
|
|
3771
3583
|
}
|
|
3772
3584
|
function useThemes() {
|
|
3773
|
-
return
|
|
3585
|
+
return useSyncExternalStore3(subscribeThemes, listThemes, listThemes);
|
|
3774
3586
|
}
|
|
3775
3587
|
function themeMode(id) {
|
|
3776
3588
|
if (id === SYSTEM_THEME) {
|
|
@@ -3954,9 +3766,9 @@ function useSshAuthProviders() {
|
|
|
3954
3766
|
|
|
3955
3767
|
// src/ui/hooks/use-action-slot.ts
|
|
3956
3768
|
init_define_import_meta_env();
|
|
3957
|
-
import { useMemo as useMemo3, useSyncExternalStore as
|
|
3769
|
+
import { useMemo as useMemo3, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
3958
3770
|
function useActionSlot(slotId, context) {
|
|
3959
|
-
const contributions2 =
|
|
3771
|
+
const contributions2 = useSyncExternalStore4(
|
|
3960
3772
|
subscribeToActionRegistry,
|
|
3961
3773
|
() => getSlotContributions(slotId),
|
|
3962
3774
|
() => getSlotContributions(slotId)
|
|
@@ -4103,6 +3915,7 @@ function sshHostToHost(h) {
|
|
|
4103
3915
|
connectionOrigin: h.connectionOrigin ?? null,
|
|
4104
3916
|
localOnly: !!h.localOnly,
|
|
4105
3917
|
sharedCopy: !!h.sharedCopy,
|
|
3918
|
+
...h.lock ? { lock: h.lock } : {},
|
|
4106
3919
|
enableSsh: h.enableSsh != null ? h.enableSsh : isSshHost,
|
|
4107
3920
|
sshPort: h.sshPort ?? (h.connectionType === "ssh" || !h.connectionType ? h.port : 22),
|
|
4108
3921
|
protocolAuth: h.protocolAuth ?? {},
|
|
@@ -4944,28 +4757,28 @@ function restoreSplitTabs(persisted, tabs, openedAt = Date.now()) {
|
|
|
4944
4757
|
|
|
4945
4758
|
// src/ui/shell/split/split-drag.ts
|
|
4946
4759
|
init_define_import_meta_env();
|
|
4947
|
-
import { useSyncExternalStore as
|
|
4760
|
+
import { useSyncExternalStore as useSyncExternalStore5 } from "react";
|
|
4948
4761
|
var state = null;
|
|
4949
4762
|
var hitTest = null;
|
|
4950
4763
|
var dropHandler = null;
|
|
4951
|
-
var
|
|
4952
|
-
function
|
|
4953
|
-
for (const listener of
|
|
4764
|
+
var listeners4 = /* @__PURE__ */ new Set();
|
|
4765
|
+
function emit3() {
|
|
4766
|
+
for (const listener of listeners4) listener();
|
|
4954
4767
|
}
|
|
4955
4768
|
function beginSplitDrag(source, x, y) {
|
|
4956
4769
|
state = { source, x, y, hover: hitTest?.(x, y, source) ?? null };
|
|
4957
|
-
|
|
4770
|
+
emit3();
|
|
4958
4771
|
}
|
|
4959
4772
|
function moveSplitDrag(x, y) {
|
|
4960
4773
|
if (!state) return;
|
|
4961
4774
|
state = { ...state, x, y, hover: hitTest?.(x, y, state.source) ?? null };
|
|
4962
|
-
|
|
4775
|
+
emit3();
|
|
4963
4776
|
}
|
|
4964
4777
|
function endSplitDrag(commit) {
|
|
4965
4778
|
const ended = state;
|
|
4966
4779
|
if (!ended) return;
|
|
4967
4780
|
state = null;
|
|
4968
|
-
|
|
4781
|
+
emit3();
|
|
4969
4782
|
if (commit && ended.hover) dropHandler?.(ended.source, ended.hover);
|
|
4970
4783
|
}
|
|
4971
4784
|
function isSplitDragging() {
|
|
@@ -4984,11 +4797,11 @@ function setSplitDropHandler(next) {
|
|
|
4984
4797
|
};
|
|
4985
4798
|
}
|
|
4986
4799
|
function subscribe2(listener) {
|
|
4987
|
-
|
|
4988
|
-
return () =>
|
|
4800
|
+
listeners4.add(listener);
|
|
4801
|
+
return () => listeners4.delete(listener);
|
|
4989
4802
|
}
|
|
4990
4803
|
function useSplitDrag() {
|
|
4991
|
-
return
|
|
4804
|
+
return useSyncExternalStore5(
|
|
4992
4805
|
subscribe2,
|
|
4993
4806
|
() => state,
|
|
4994
4807
|
() => null
|
|
@@ -5027,18 +4840,18 @@ function dropTargetRect(rect, target) {
|
|
|
5027
4840
|
|
|
5028
4841
|
// src/ui/shell/split/split-targets.ts
|
|
5029
4842
|
init_define_import_meta_env();
|
|
5030
|
-
import { useSyncExternalStore as
|
|
4843
|
+
import { useSyncExternalStore as useSyncExternalStore6 } from "react";
|
|
5031
4844
|
var EMPTY2 = { splits: [], canStartSplit: false };
|
|
5032
|
-
var
|
|
4845
|
+
var snapshot2 = EMPTY2;
|
|
5033
4846
|
var snapshotKey = "";
|
|
5034
4847
|
var opener = null;
|
|
5035
|
-
var
|
|
4848
|
+
var listeners5 = /* @__PURE__ */ new Set();
|
|
5036
4849
|
function publishSplitTargets(next) {
|
|
5037
4850
|
const key = JSON.stringify(next);
|
|
5038
4851
|
if (key === snapshotKey) return;
|
|
5039
4852
|
snapshotKey = key;
|
|
5040
|
-
|
|
5041
|
-
for (const listener of
|
|
4853
|
+
snapshot2 = next;
|
|
4854
|
+
for (const listener of listeners5) listener();
|
|
5042
4855
|
}
|
|
5043
4856
|
function setSplitOpener(next) {
|
|
5044
4857
|
opener = next;
|
|
@@ -5054,13 +4867,13 @@ function openInSplit(target, open) {
|
|
|
5054
4867
|
else open();
|
|
5055
4868
|
}
|
|
5056
4869
|
function subscribe3(listener) {
|
|
5057
|
-
|
|
5058
|
-
return () =>
|
|
4870
|
+
listeners5.add(listener);
|
|
4871
|
+
return () => listeners5.delete(listener);
|
|
5059
4872
|
}
|
|
5060
4873
|
function useSplitTargets() {
|
|
5061
|
-
return
|
|
4874
|
+
return useSyncExternalStore6(
|
|
5062
4875
|
subscribe3,
|
|
5063
|
-
() =>
|
|
4876
|
+
() => snapshot2,
|
|
5064
4877
|
() => EMPTY2
|
|
5065
4878
|
);
|
|
5066
4879
|
}
|
|
@@ -5102,25 +4915,25 @@ function buildLayoutTabSnapshots(tabs, genSlotId = createId) {
|
|
|
5102
4915
|
}));
|
|
5103
4916
|
return { snapshots: snapshots2, slotIdByTabId };
|
|
5104
4917
|
}
|
|
5105
|
-
function snapshotData(
|
|
5106
|
-
if (
|
|
4918
|
+
function snapshotData(snapshot3) {
|
|
4919
|
+
if (snapshot3.data) return snapshot3.data;
|
|
5107
4920
|
const legacy = {};
|
|
5108
|
-
if (
|
|
5109
|
-
if (
|
|
5110
|
-
legacy.initialFilePath =
|
|
5111
|
-
if (
|
|
4921
|
+
if (snapshot3.fleetId !== void 0) legacy.fleetId = snapshot3.fleetId;
|
|
4922
|
+
if (snapshot3.initialFilePath)
|
|
4923
|
+
legacy.initialFilePath = snapshot3.initialFilePath;
|
|
4924
|
+
if (snapshot3.initialPath) legacy.initialPath = snapshot3.initialPath;
|
|
5112
4925
|
return Object.keys(legacy).length > 0 ? legacy : void 0;
|
|
5113
4926
|
}
|
|
5114
|
-
function resolveLayoutTabTarget(
|
|
4927
|
+
function resolveLayoutTabTarget(snapshot3, allHosts) {
|
|
5115
4928
|
let host;
|
|
5116
|
-
if (
|
|
5117
|
-
host = allHosts.find((h) => h.syncId ===
|
|
4929
|
+
if (snapshot3.hostSyncId) {
|
|
4930
|
+
host = allHosts.find((h) => h.syncId === snapshot3.hostSyncId);
|
|
5118
4931
|
if (!host) return { kind: "skip" };
|
|
5119
4932
|
}
|
|
5120
|
-
if (opensAsSingleton(
|
|
4933
|
+
if (opensAsSingleton(snapshot3.type, !!host)) {
|
|
5121
4934
|
return { kind: "singleton", host };
|
|
5122
4935
|
}
|
|
5123
|
-
if (!host && isUnregisteredPluginTabType(
|
|
4936
|
+
if (!host && isUnregisteredPluginTabType(snapshot3.type)) {
|
|
5124
4937
|
return { kind: "singleton" };
|
|
5125
4938
|
}
|
|
5126
4939
|
return host ? { kind: "host", host } : { kind: "skip" };
|
|
@@ -5400,11 +5213,11 @@ function createTabStageStore() {
|
|
|
5400
5213
|
const paneEls = /* @__PURE__ */ new Map();
|
|
5401
5214
|
const listeners9 = /* @__PURE__ */ new Set();
|
|
5402
5215
|
let normalView = null;
|
|
5403
|
-
let
|
|
5216
|
+
let version4 = 0;
|
|
5404
5217
|
let order2 = [];
|
|
5405
5218
|
let lastAnimatedTabId = null;
|
|
5406
5219
|
const bump = () => {
|
|
5407
|
-
|
|
5220
|
+
version4 += 1;
|
|
5408
5221
|
for (const listener of listeners9) listener();
|
|
5409
5222
|
};
|
|
5410
5223
|
function getNode(tabId, ownBackground) {
|
|
@@ -5512,7 +5325,7 @@ function createTabStageStore() {
|
|
|
5512
5325
|
listeners9.delete(listener);
|
|
5513
5326
|
};
|
|
5514
5327
|
},
|
|
5515
|
-
version: () =>
|
|
5328
|
+
version: () => version4
|
|
5516
5329
|
};
|
|
5517
5330
|
}
|
|
5518
5331
|
|
|
@@ -6888,7 +6701,7 @@ function useSplit({
|
|
|
6888
6701
|
useEffect9(() => {
|
|
6889
6702
|
if (!focusedPaneId || !focusedPaneTabId) return;
|
|
6890
6703
|
let attempts = 0;
|
|
6891
|
-
let
|
|
6704
|
+
let timer;
|
|
6892
6705
|
const attempt = () => {
|
|
6893
6706
|
const focused = document.activeElement;
|
|
6894
6707
|
const paneEl = paneEls.get(focusedPaneId);
|
|
@@ -6904,12 +6717,12 @@ function useSplit({
|
|
|
6904
6717
|
handle.focus();
|
|
6905
6718
|
return;
|
|
6906
6719
|
}
|
|
6907
|
-
if (attempts++ < 10)
|
|
6720
|
+
if (attempts++ < 10) timer = setTimeout(attempt, 100);
|
|
6908
6721
|
};
|
|
6909
6722
|
const frame = requestAnimationFrame(attempt);
|
|
6910
6723
|
return () => {
|
|
6911
6724
|
cancelAnimationFrame(frame);
|
|
6912
|
-
if (
|
|
6725
|
+
if (timer) clearTimeout(timer);
|
|
6913
6726
|
};
|
|
6914
6727
|
}, [focusedPaneId, focusedPaneTabId]);
|
|
6915
6728
|
useEffect9(() => {
|
|
@@ -7027,34 +6840,34 @@ function useWorkspaceLayout(tabsState, regions) {
|
|
|
7027
6840
|
try {
|
|
7028
6841
|
const slotIdToNewTabId = /* @__PURE__ */ new Map();
|
|
7029
6842
|
const skippedTabs = [];
|
|
7030
|
-
for (const
|
|
7031
|
-
const target = resolveLayoutTabTarget(
|
|
6843
|
+
for (const snapshot3 of payload.tabs) {
|
|
6844
|
+
const target = resolveLayoutTabTarget(snapshot3, hostsRef.current);
|
|
7032
6845
|
if (target.kind === "skip") {
|
|
7033
|
-
skippedTabs.push(
|
|
6846
|
+
skippedTabs.push(snapshot3.hostNameSnapshot || snapshot3.label);
|
|
7034
6847
|
continue;
|
|
7035
6848
|
}
|
|
7036
6849
|
if (target.kind === "singleton") {
|
|
7037
6850
|
const newTabId = tabsState.openSingletonTab(
|
|
7038
|
-
|
|
6851
|
+
snapshot3.type,
|
|
7039
6852
|
void 0,
|
|
7040
6853
|
target.host,
|
|
7041
|
-
snapshotData(
|
|
6854
|
+
snapshotData(snapshot3)
|
|
7042
6855
|
);
|
|
7043
|
-
slotIdToNewTabId.set(
|
|
6856
|
+
slotIdToNewTabId.set(snapshot3.slotId, newTabId ?? snapshot3.type);
|
|
7044
6857
|
continue;
|
|
7045
6858
|
}
|
|
7046
6859
|
if (target.kind === "host") {
|
|
7047
6860
|
const newTabId = tabsState.openTab(
|
|
7048
6861
|
target.host,
|
|
7049
|
-
|
|
6862
|
+
snapshot3.type,
|
|
7050
6863
|
{
|
|
7051
6864
|
instanceId: createId(),
|
|
7052
6865
|
restoredSessionId: null,
|
|
7053
|
-
savedLabel:
|
|
6866
|
+
savedLabel: snapshot3.customLabel ?? snapshot3.label
|
|
7054
6867
|
},
|
|
7055
|
-
{ data: snapshotData(
|
|
6868
|
+
{ data: snapshotData(snapshot3) }
|
|
7056
6869
|
);
|
|
7057
|
-
slotIdToNewTabId.set(
|
|
6870
|
+
slotIdToNewTabId.set(snapshot3.slotId, newTabId);
|
|
7058
6871
|
}
|
|
7059
6872
|
}
|
|
7060
6873
|
const splitIdBySlotId = /* @__PURE__ */ new Map();
|
|
@@ -7141,7 +6954,7 @@ function useShellKeybindings({
|
|
|
7141
6954
|
toggleFullscreenRef.current = toggleFullscreen;
|
|
7142
6955
|
useEffect11(() => {
|
|
7143
6956
|
let cancelled = false;
|
|
7144
|
-
const
|
|
6957
|
+
const load2 = () => {
|
|
7145
6958
|
getUserPreferences().then((prefs) => {
|
|
7146
6959
|
if (cancelled) return;
|
|
7147
6960
|
globalKeybindingsRef.current = parseCustomKeybindings(
|
|
@@ -7150,11 +6963,11 @@ function useShellKeybindings({
|
|
|
7150
6963
|
}).catch(() => {
|
|
7151
6964
|
});
|
|
7152
6965
|
};
|
|
7153
|
-
|
|
7154
|
-
window.addEventListener("customKeybindingsChanged",
|
|
6966
|
+
load2();
|
|
6967
|
+
window.addEventListener("customKeybindingsChanged", load2);
|
|
7155
6968
|
return () => {
|
|
7156
6969
|
cancelled = true;
|
|
7157
|
-
window.removeEventListener("customKeybindingsChanged",
|
|
6970
|
+
window.removeEventListener("customKeybindingsChanged", load2);
|
|
7158
6971
|
};
|
|
7159
6972
|
}, []);
|
|
7160
6973
|
useEffect11(() => {
|
|
@@ -7519,19 +7332,19 @@ function useShellLifecycle({
|
|
|
7519
7332
|
|
|
7520
7333
|
// src/ui/shell/controller/shell-store.ts
|
|
7521
7334
|
init_define_import_meta_env();
|
|
7522
|
-
import { useSyncExternalStore as
|
|
7335
|
+
import { useSyncExternalStore as useSyncExternalStore7 } from "react";
|
|
7523
7336
|
var current = null;
|
|
7524
|
-
var
|
|
7337
|
+
var listeners6 = /* @__PURE__ */ new Set();
|
|
7525
7338
|
function publishShellController(next) {
|
|
7526
7339
|
if (next === current) return;
|
|
7527
7340
|
current = next;
|
|
7528
|
-
for (const listener of
|
|
7341
|
+
for (const listener of listeners6) listener();
|
|
7529
7342
|
}
|
|
7530
7343
|
function useShellSnapshot() {
|
|
7531
|
-
return
|
|
7344
|
+
return useSyncExternalStore7(
|
|
7532
7345
|
(listener) => {
|
|
7533
|
-
|
|
7534
|
-
return () =>
|
|
7346
|
+
listeners6.add(listener);
|
|
7347
|
+
return () => listeners6.delete(listener);
|
|
7535
7348
|
},
|
|
7536
7349
|
() => current,
|
|
7537
7350
|
() => current
|
|
@@ -7602,7 +7415,6 @@ function ShellControllerProvider({
|
|
|
7602
7415
|
});
|
|
7603
7416
|
openSingletonRef.current = tabsState.openSingletonTab;
|
|
7604
7417
|
const { tabs, activeTabId } = tabsState;
|
|
7605
|
-
useSyncStatus();
|
|
7606
7418
|
const palette = {
|
|
7607
7419
|
isOpen: paletteOpen,
|
|
7608
7420
|
open: () => setPaletteOpen(true),
|
|
@@ -7801,25 +7613,25 @@ function computeAdaptivePollDelay(policy, state2, random = Math.random) {
|
|
|
7801
7613
|
const jitter = base * jitterRatio * (random() * 2 - 1);
|
|
7802
7614
|
return Math.max(min, Math.min(max, Math.round(base + jitter)));
|
|
7803
7615
|
}
|
|
7804
|
-
function runAdaptivePolling(
|
|
7616
|
+
function runAdaptivePolling(poll, policy, options = {}) {
|
|
7805
7617
|
const enabled = options.enabled ?? (() => true);
|
|
7806
7618
|
const visible = options.visible ?? (() => typeof document === "undefined" || document.visibilityState !== "hidden");
|
|
7807
7619
|
const state2 = {
|
|
7808
7620
|
stablePolls: 0,
|
|
7809
7621
|
consecutiveFailures: 0
|
|
7810
7622
|
};
|
|
7811
|
-
let
|
|
7623
|
+
let timer = null;
|
|
7812
7624
|
let stopped = false;
|
|
7813
7625
|
let inFlight = false;
|
|
7814
7626
|
const clearTimer = () => {
|
|
7815
|
-
if (!
|
|
7816
|
-
clearTimeout(
|
|
7817
|
-
|
|
7627
|
+
if (!timer) return;
|
|
7628
|
+
clearTimeout(timer);
|
|
7629
|
+
timer = null;
|
|
7818
7630
|
};
|
|
7819
|
-
const
|
|
7631
|
+
const schedule = () => {
|
|
7820
7632
|
clearTimer();
|
|
7821
7633
|
if (stopped || !enabled() || !visible()) return;
|
|
7822
|
-
|
|
7634
|
+
timer = setTimeout(
|
|
7823
7635
|
() => void tick(),
|
|
7824
7636
|
Math.min(
|
|
7825
7637
|
policy.maxIntervalMs,
|
|
@@ -7834,7 +7646,7 @@ function runAdaptivePolling(poll2, policy, options = {}) {
|
|
|
7834
7646
|
inFlight = true;
|
|
7835
7647
|
const startedAt = Date.now();
|
|
7836
7648
|
try {
|
|
7837
|
-
const changed = await
|
|
7649
|
+
const changed = await poll();
|
|
7838
7650
|
state2.consecutiveFailures = 0;
|
|
7839
7651
|
state2.stablePolls = changed === false ? state2.stablePolls + 1 : 0;
|
|
7840
7652
|
} catch (error) {
|
|
@@ -7844,7 +7656,7 @@ function runAdaptivePolling(poll2, policy, options = {}) {
|
|
|
7844
7656
|
} finally {
|
|
7845
7657
|
state2.lastPollDurationMs = Date.now() - startedAt;
|
|
7846
7658
|
inFlight = false;
|
|
7847
|
-
|
|
7659
|
+
schedule();
|
|
7848
7660
|
}
|
|
7849
7661
|
};
|
|
7850
7662
|
const onVisibility = () => {
|
|
@@ -7860,7 +7672,7 @@ function runAdaptivePolling(poll2, policy, options = {}) {
|
|
|
7860
7672
|
document.addEventListener("visibilitychange", onVisibility);
|
|
7861
7673
|
}
|
|
7862
7674
|
if (options.runImmediately ?? true) void tick();
|
|
7863
|
-
else
|
|
7675
|
+
else schedule();
|
|
7864
7676
|
return () => {
|
|
7865
7677
|
stopped = true;
|
|
7866
7678
|
clearTimer();
|
|
@@ -7886,7 +7698,7 @@ import {
|
|
|
7886
7698
|
useCallback as useCallback7,
|
|
7887
7699
|
useRef as useRef7,
|
|
7888
7700
|
useMemo as useMemo6,
|
|
7889
|
-
useSyncExternalStore as
|
|
7701
|
+
useSyncExternalStore as useSyncExternalStore8,
|
|
7890
7702
|
useState as useState13
|
|
7891
7703
|
} from "react";
|
|
7892
7704
|
|
|
@@ -7998,7 +7810,7 @@ function ServerStatusProvider({
|
|
|
7998
7810
|
storeRef.current = new ServerStatusStore();
|
|
7999
7811
|
}
|
|
8000
7812
|
const store = storeRef.current;
|
|
8001
|
-
const [
|
|
7813
|
+
const [version4, setVersion] = useState13(0);
|
|
8002
7814
|
const mountedRef = useRef7(true);
|
|
8003
7815
|
const refreshInFlightRef = useRef7(null);
|
|
8004
7816
|
useEffect14(() => store.subscribeAll(() => setVersion((v) => v + 1)), [store]);
|
|
@@ -8081,7 +7893,7 @@ function ServerStatusProvider({
|
|
|
8081
7893
|
}),
|
|
8082
7894
|
// version refreshes the statuses/initialLoadComplete snapshots
|
|
8083
7895
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
8084
|
-
[
|
|
7896
|
+
[version4, refreshStatuses, getStatus]
|
|
8085
7897
|
);
|
|
8086
7898
|
return /* @__PURE__ */ jsx8(StatusStoreContext.Provider, { value: store, children: /* @__PURE__ */ jsx8(ServerStatusContext.Provider, { value: contextValue, children }) });
|
|
8087
7899
|
}
|
|
@@ -8103,7 +7915,7 @@ function useServerStatus() {
|
|
|
8103
7915
|
}
|
|
8104
7916
|
function useHostStatus(hostId, statusCheckEnabled = true) {
|
|
8105
7917
|
const store = useStatusStore();
|
|
8106
|
-
const status =
|
|
7918
|
+
const status = useSyncExternalStore8(
|
|
8107
7919
|
(onChange) => store.subscribeHost(hostId, onChange),
|
|
8108
7920
|
() => store.getStatus(hostId),
|
|
8109
7921
|
() => store.getStatus(hostId)
|
|
@@ -8112,7 +7924,7 @@ function useHostStatus(hostId, statusCheckEnabled = true) {
|
|
|
8112
7924
|
}
|
|
8113
7925
|
function useServerStatusMeta() {
|
|
8114
7926
|
const store = useStatusStore();
|
|
8115
|
-
|
|
7927
|
+
useSyncExternalStore8(
|
|
8116
7928
|
(onChange) => store.subscribeMeta(onChange),
|
|
8117
7929
|
() => store.getMetaSnapshot(),
|
|
8118
7930
|
() => store.getMetaSnapshot()
|
|
@@ -8122,7 +7934,7 @@ function useServerStatusMeta() {
|
|
|
8122
7934
|
var noStatus = () => "unknown";
|
|
8123
7935
|
function useOptionalHostStatusEntry(hostId) {
|
|
8124
7936
|
const store = useContext4(StatusStoreContext);
|
|
8125
|
-
const status =
|
|
7937
|
+
const status = useSyncExternalStore8(
|
|
8126
7938
|
(onChange) => store && hostId !== void 0 ? store.subscribeHost(hostId, onChange) : () => {
|
|
8127
7939
|
},
|
|
8128
7940
|
() => store && hostId !== void 0 ? store.getStatus(hostId) : "unknown",
|
|
@@ -8374,7 +8186,7 @@ var pluginHostBridge = {
|
|
|
8374
8186
|
window.removeEventListener(PLUGIN_SETTINGS_CHANGED_EVENT, onChanged);
|
|
8375
8187
|
};
|
|
8376
8188
|
}, [pluginId, scope, numericHostId]);
|
|
8377
|
-
const
|
|
8189
|
+
const save2 = useCallback8(
|
|
8378
8190
|
async (values) => {
|
|
8379
8191
|
const saved = await SETTINGS_WRITERS[scope](
|
|
8380
8192
|
pluginId,
|
|
@@ -8385,7 +8197,7 @@ var pluginHostBridge = {
|
|
|
8385
8197
|
},
|
|
8386
8198
|
[pluginId, scope, numericHostId]
|
|
8387
8199
|
);
|
|
8388
|
-
return useMemo8(() => ({ ...state2, save }), [state2,
|
|
8200
|
+
return useMemo8(() => ({ ...state2, save: save2 }), [state2, save2]);
|
|
8389
8201
|
},
|
|
8390
8202
|
useHost(hostId) {
|
|
8391
8203
|
const pluginId = usePluginScope();
|
|
@@ -8558,7 +8370,7 @@ function onRemoteServerChange(listener) {
|
|
|
8558
8370
|
|
|
8559
8371
|
// src/ui/look/layout-registry.ts
|
|
8560
8372
|
init_define_import_meta_env();
|
|
8561
|
-
import { useSyncExternalStore as
|
|
8373
|
+
import { useSyncExternalStore as useSyncExternalStore9 } from "react";
|
|
8562
8374
|
var descriptorSnapshot = [];
|
|
8563
8375
|
var descriptorListeners = /* @__PURE__ */ new Set();
|
|
8564
8376
|
var registered = createRegistry();
|
|
@@ -8584,7 +8396,7 @@ function subscribeDescriptors(listener) {
|
|
|
8584
8396
|
};
|
|
8585
8397
|
}
|
|
8586
8398
|
function useLayouts() {
|
|
8587
|
-
return
|
|
8399
|
+
return useSyncExternalStore9(subscribeDescriptors, listLayouts, listLayouts);
|
|
8588
8400
|
}
|
|
8589
8401
|
function layoutLabel(layout, t) {
|
|
8590
8402
|
if (!layout.pluginId) return layout.label;
|
|
@@ -8595,6 +8407,86 @@ function layoutLabel(layout, t) {
|
|
|
8595
8407
|
|
|
8596
8408
|
// src/ui/plugin-host/app.ts
|
|
8597
8409
|
init_define_import_meta_env();
|
|
8410
|
+
import { useEffect as useEffect16 } from "react";
|
|
8411
|
+
|
|
8412
|
+
// src/ui/shell/companions.ts
|
|
8413
|
+
init_define_import_meta_env();
|
|
8414
|
+
import { useSyncExternalStore as useSyncExternalStore10 } from "react";
|
|
8415
|
+
var registry5 = createRegistry(byOrderThenId);
|
|
8416
|
+
var registerCompanionDef = registry5.register;
|
|
8417
|
+
var getCompanionDef = registry5.get;
|
|
8418
|
+
var listCompanionDefs = registry5.list;
|
|
8419
|
+
var useCompanionDefs = registry5.useList;
|
|
8420
|
+
var resetCompanions = registry5.reset;
|
|
8421
|
+
function companionApplies(def, tab) {
|
|
8422
|
+
if (!tab.host) return false;
|
|
8423
|
+
if (def.tabTypes?.length && !def.tabTypes.includes(tab.type)) return false;
|
|
8424
|
+
return def.when ? def.when(tab, tab.host) : true;
|
|
8425
|
+
}
|
|
8426
|
+
var STORAGE_KEY = "termix:companions";
|
|
8427
|
+
var EMPTY3 = { openId: null, seen: false };
|
|
8428
|
+
var states = /* @__PURE__ */ new Map();
|
|
8429
|
+
var listeners7 = /* @__PURE__ */ new Set();
|
|
8430
|
+
var version2 = 0;
|
|
8431
|
+
function load() {
|
|
8432
|
+
try {
|
|
8433
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
8434
|
+
if (!raw) return;
|
|
8435
|
+
const parsed = JSON.parse(raw);
|
|
8436
|
+
states = new Map(Object.entries(parsed));
|
|
8437
|
+
} catch {
|
|
8438
|
+
}
|
|
8439
|
+
}
|
|
8440
|
+
function save() {
|
|
8441
|
+
try {
|
|
8442
|
+
const entries = [...states.entries()].slice(-200);
|
|
8443
|
+
localStorage.setItem(
|
|
8444
|
+
STORAGE_KEY,
|
|
8445
|
+
JSON.stringify(Object.fromEntries(entries))
|
|
8446
|
+
);
|
|
8447
|
+
} catch {
|
|
8448
|
+
}
|
|
8449
|
+
}
|
|
8450
|
+
load();
|
|
8451
|
+
function companionKey(tab) {
|
|
8452
|
+
return tab.instanceId ?? tab.id;
|
|
8453
|
+
}
|
|
8454
|
+
function getCompanionState(key) {
|
|
8455
|
+
return states.get(key) ?? EMPTY3;
|
|
8456
|
+
}
|
|
8457
|
+
function patchCompanionState(key, patch) {
|
|
8458
|
+
const next = { ...getCompanionState(key), ...patch };
|
|
8459
|
+
states = new Map(states);
|
|
8460
|
+
states.delete(key);
|
|
8461
|
+
states.set(key, next);
|
|
8462
|
+
version2 += 1;
|
|
8463
|
+
save();
|
|
8464
|
+
for (const listener of listeners7) listener();
|
|
8465
|
+
}
|
|
8466
|
+
function subscribe4(listener) {
|
|
8467
|
+
listeners7.add(listener);
|
|
8468
|
+
return () => listeners7.delete(listener);
|
|
8469
|
+
}
|
|
8470
|
+
function useCompanionState(key) {
|
|
8471
|
+
useSyncExternalStore10(
|
|
8472
|
+
subscribe4,
|
|
8473
|
+
() => version2,
|
|
8474
|
+
() => version2
|
|
8475
|
+
);
|
|
8476
|
+
return getCompanionState(key);
|
|
8477
|
+
}
|
|
8478
|
+
function toggleCompanion(tab, id) {
|
|
8479
|
+
const key = companionKey(tab);
|
|
8480
|
+
const current2 = getCompanionState(key);
|
|
8481
|
+
const target = id ?? current2.openId ?? listCompanionDefs().find((def) => companionApplies(def, tab))?.id ?? null;
|
|
8482
|
+
if (!target) return;
|
|
8483
|
+
patchCompanionState(key, {
|
|
8484
|
+
seen: true,
|
|
8485
|
+
openId: current2.openId === target ? null : target
|
|
8486
|
+
});
|
|
8487
|
+
}
|
|
8488
|
+
|
|
8489
|
+
// src/ui/plugin-host/app.ts
|
|
8598
8490
|
var ONBOARDING_ID = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
8599
8491
|
function createDocsApi(manifest) {
|
|
8600
8492
|
const url = pluginDocsUrl(manifest?.docs);
|
|
@@ -8689,6 +8581,40 @@ function createPluginApp(pluginId, manifest, contributes, options = {}) {
|
|
|
8689
8581
|
})
|
|
8690
8582
|
);
|
|
8691
8583
|
},
|
|
8584
|
+
registerCompanion(id, component, options2 = {}) {
|
|
8585
|
+
const useDefaults = options2.useDefaults;
|
|
8586
|
+
const Defaults = useDefaults ? scoped(function CompanionDefaultsReader({
|
|
8587
|
+
onValue
|
|
8588
|
+
}) {
|
|
8589
|
+
const value = useDefaults();
|
|
8590
|
+
const { open, side, size, edgeButton } = value;
|
|
8591
|
+
useEffect16(() => {
|
|
8592
|
+
onValue({ open, side, size, edgeButton });
|
|
8593
|
+
}, [onValue, open, side, size, edgeButton]);
|
|
8594
|
+
return null;
|
|
8595
|
+
}) : void 0;
|
|
8596
|
+
return track(
|
|
8597
|
+
registerCompanionDef({
|
|
8598
|
+
id: `${pluginId}.${id}`,
|
|
8599
|
+
pluginId,
|
|
8600
|
+
component: scoped(
|
|
8601
|
+
component
|
|
8602
|
+
),
|
|
8603
|
+
icon: withIconBoundary(pluginId, options2.icon),
|
|
8604
|
+
titleKey: options2.titleKey ? key(options2.titleKey) : void 0,
|
|
8605
|
+
order: options2.order,
|
|
8606
|
+
tabTypes: options2.tabTypes,
|
|
8607
|
+
when: options2.when,
|
|
8608
|
+
Defaults
|
|
8609
|
+
})
|
|
8610
|
+
);
|
|
8611
|
+
},
|
|
8612
|
+
toggleCompanion(tab, id) {
|
|
8613
|
+
toggleCompanion(
|
|
8614
|
+
tab,
|
|
8615
|
+
id ? `${pluginId}.${id}` : void 0
|
|
8616
|
+
);
|
|
8617
|
+
},
|
|
8692
8618
|
registerTab(type, component, options2 = {}) {
|
|
8693
8619
|
requireDeclared("tab", type, "tab type");
|
|
8694
8620
|
return track(
|
|
@@ -8940,8 +8866,8 @@ function createPluginApp(pluginId, manifest, contributes, options = {}) {
|
|
|
8940
8866
|
},
|
|
8941
8867
|
registerOnboardingStep(step) {
|
|
8942
8868
|
requireStepId(step.id, "onboarding step");
|
|
8943
|
-
const
|
|
8944
|
-
if (!Number.isInteger(
|
|
8869
|
+
const version4 = step.version ?? 1;
|
|
8870
|
+
if (!Number.isInteger(version4) || version4 < 1) {
|
|
8945
8871
|
throw new Error(
|
|
8946
8872
|
`${pluginId}: onboarding step "${step.id}" needs a whole version of 1 or more`
|
|
8947
8873
|
);
|
|
@@ -8951,7 +8877,7 @@ function createPluginApp(pluginId, manifest, contributes, options = {}) {
|
|
|
8951
8877
|
onboardingSteps.register({
|
|
8952
8878
|
id: pluginStepKey(pluginId, step.id),
|
|
8953
8879
|
pluginId,
|
|
8954
|
-
version:
|
|
8880
|
+
version: version4,
|
|
8955
8881
|
titleKey: key(step.titleKey),
|
|
8956
8882
|
descriptionKey: step.descriptionKey ? key(step.descriptionKey) : void 0,
|
|
8957
8883
|
icon: step.icon ? withIconBoundary(pluginId, step.icon) : void 0,
|
|
@@ -9091,24 +9017,24 @@ function createPluginApp(pluginId, manifest, contributes, options = {}) {
|
|
|
9091
9017
|
|
|
9092
9018
|
// src/ui/hooks/use-installed-plugins.ts
|
|
9093
9019
|
init_define_import_meta_env();
|
|
9094
|
-
import { useEffect as
|
|
9020
|
+
import { useEffect as useEffect17, useState as useState15 } from "react";
|
|
9095
9021
|
function useInstalledPlugins() {
|
|
9096
9022
|
const [plugins, setPlugins] = useState15([]);
|
|
9097
|
-
|
|
9023
|
+
useEffect17(() => {
|
|
9098
9024
|
let cancelled = false;
|
|
9099
9025
|
let request = 0;
|
|
9100
|
-
const
|
|
9026
|
+
const load2 = () => {
|
|
9101
9027
|
const current2 = ++request;
|
|
9102
9028
|
void getPlugins().then((loaded) => {
|
|
9103
9029
|
if (!cancelled && current2 === request) setPlugins(loaded);
|
|
9104
9030
|
}).catch(() => {
|
|
9105
9031
|
});
|
|
9106
9032
|
};
|
|
9107
|
-
|
|
9108
|
-
window.addEventListener(PLUGINS_CHANGED_EVENT,
|
|
9033
|
+
load2();
|
|
9034
|
+
window.addEventListener(PLUGINS_CHANGED_EVENT, load2);
|
|
9109
9035
|
return () => {
|
|
9110
9036
|
cancelled = true;
|
|
9111
|
-
window.removeEventListener(PLUGINS_CHANGED_EVENT,
|
|
9037
|
+
window.removeEventListener(PLUGINS_CHANGED_EVENT, load2);
|
|
9112
9038
|
};
|
|
9113
9039
|
}, []);
|
|
9114
9040
|
return plugins;
|
|
@@ -9529,10 +9455,10 @@ function ComponentSlot({
|
|
|
9529
9455
|
// src/ui/shell/tab-handles.ts
|
|
9530
9456
|
init_define_import_meta_env();
|
|
9531
9457
|
import { useSyncExternalStore as useSyncExternalStore11 } from "react";
|
|
9532
|
-
var
|
|
9458
|
+
var version3 = 0;
|
|
9533
9459
|
var listeners8 = /* @__PURE__ */ new Set();
|
|
9534
9460
|
var callbacks = /* @__PURE__ */ new WeakMap();
|
|
9535
|
-
function
|
|
9461
|
+
function subscribe5(listener) {
|
|
9536
9462
|
listeners8.add(listener);
|
|
9537
9463
|
return () => listeners8.delete(listener);
|
|
9538
9464
|
}
|
|
@@ -9543,7 +9469,7 @@ function trackTabHandle(ref) {
|
|
|
9543
9469
|
callback = (value) => {
|
|
9544
9470
|
if (ref.current === value) return;
|
|
9545
9471
|
ref.current = value;
|
|
9546
|
-
|
|
9472
|
+
version3 += 1;
|
|
9547
9473
|
for (const listener of listeners8) listener();
|
|
9548
9474
|
};
|
|
9549
9475
|
callbacks.set(ref, callback);
|
|
@@ -9552,9 +9478,9 @@ function trackTabHandle(ref) {
|
|
|
9552
9478
|
}
|
|
9553
9479
|
function useTabHandlesVersion() {
|
|
9554
9480
|
return useSyncExternalStore11(
|
|
9555
|
-
|
|
9556
|
-
() =>
|
|
9557
|
-
() =>
|
|
9481
|
+
subscribe5,
|
|
9482
|
+
() => version3,
|
|
9483
|
+
() => version3
|
|
9558
9484
|
);
|
|
9559
9485
|
}
|
|
9560
9486
|
|
|
@@ -9998,8 +9924,8 @@ function runAdaptiveBackgroundTask(kind, action, task, options = {}) {
|
|
|
9998
9924
|
|
|
9999
9925
|
// src/ui/shell/tabUtils.tsx
|
|
10000
9926
|
init_define_import_meta_env();
|
|
10001
|
-
import { lazy, memo, Suspense } from "react";
|
|
10002
|
-
import { useTranslation as
|
|
9927
|
+
import { lazy, memo as memo2, Suspense } from "react";
|
|
9928
|
+
import { useTranslation as useTranslation9 } from "react-i18next";
|
|
10003
9929
|
|
|
10004
9930
|
// src/ui/lib/host-to-ssh-host.ts
|
|
10005
9931
|
init_define_import_meta_env();
|
|
@@ -10037,10 +9963,258 @@ function hostToSSHHost(h) {
|
|
|
10037
9963
|
};
|
|
10038
9964
|
}
|
|
10039
9965
|
|
|
9966
|
+
// src/ui/shell/CompanionFrame.tsx
|
|
9967
|
+
init_define_import_meta_env();
|
|
9968
|
+
import {
|
|
9969
|
+
memo,
|
|
9970
|
+
useCallback as useCallback9,
|
|
9971
|
+
useEffect as useEffect18,
|
|
9972
|
+
useMemo as useMemo10,
|
|
9973
|
+
useRef as useRef8,
|
|
9974
|
+
useState as useState16
|
|
9975
|
+
} from "react";
|
|
9976
|
+
import { useTranslation as useTranslation8 } from "react-i18next";
|
|
9977
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
9978
|
+
var DEFAULT_SIDE_SIZE = 360;
|
|
9979
|
+
var DEFAULT_BOTTOM_SIZE = 280;
|
|
9980
|
+
var MIN_SIZE = 200;
|
|
9981
|
+
function DefaultsReader({
|
|
9982
|
+
def,
|
|
9983
|
+
onValue
|
|
9984
|
+
}) {
|
|
9985
|
+
const Reader = def.Defaults;
|
|
9986
|
+
const report = useCallback9(
|
|
9987
|
+
(value) => onValue(def.id, value),
|
|
9988
|
+
[def.id, onValue]
|
|
9989
|
+
);
|
|
9990
|
+
return Reader ? /* @__PURE__ */ jsx13(Reader, { onValue: report }) : null;
|
|
9991
|
+
}
|
|
9992
|
+
function sideIcon(side) {
|
|
9993
|
+
if (side === "left") return ArrowLeftToLine;
|
|
9994
|
+
if (side === "bottom") return ArrowDownToLine;
|
|
9995
|
+
return ArrowRightToLine;
|
|
9996
|
+
}
|
|
9997
|
+
var CompanionFrame = memo(function CompanionFrame2({
|
|
9998
|
+
tab,
|
|
9999
|
+
isVisible,
|
|
10000
|
+
children
|
|
10001
|
+
}) {
|
|
10002
|
+
const defs = useCompanionDefs();
|
|
10003
|
+
const applicable = useMemo10(
|
|
10004
|
+
() => defs.filter((def) => companionApplies(def, tab)),
|
|
10005
|
+
// tab.host and tab.type decide it
|
|
10006
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
10007
|
+
[defs, tab.type, tab.host]
|
|
10008
|
+
);
|
|
10009
|
+
if (applicable.length === 0) return /* @__PURE__ */ jsx13(Fragment3, { children });
|
|
10010
|
+
return /* @__PURE__ */ jsx13(CompanionLayout, { tab, defs: applicable, isVisible, children });
|
|
10011
|
+
});
|
|
10012
|
+
function CompanionLayout({
|
|
10013
|
+
tab,
|
|
10014
|
+
defs,
|
|
10015
|
+
isVisible,
|
|
10016
|
+
children
|
|
10017
|
+
}) {
|
|
10018
|
+
const { t } = useTranslation8();
|
|
10019
|
+
const isMobile = useIsMobile();
|
|
10020
|
+
const key = companionKey(tab);
|
|
10021
|
+
const state2 = useCompanionState(key);
|
|
10022
|
+
const [defaults3, setDefaults] = useState16(
|
|
10023
|
+
{}
|
|
10024
|
+
);
|
|
10025
|
+
const [dragging, setDragging] = useState16(false);
|
|
10026
|
+
const [mounted, setMounted] = useState16(/* @__PURE__ */ new Set());
|
|
10027
|
+
const rootRef = useRef8(null);
|
|
10028
|
+
const onDefaults = useCallback9((id, value) => {
|
|
10029
|
+
setDefaults((prev) => {
|
|
10030
|
+
const old = prev[id];
|
|
10031
|
+
if (old && old.open === value.open && old.side === value.side && old.size === value.size && old.edgeButton === value.edgeButton) {
|
|
10032
|
+
return prev;
|
|
10033
|
+
}
|
|
10034
|
+
return { ...prev, [id]: value };
|
|
10035
|
+
});
|
|
10036
|
+
}, []);
|
|
10037
|
+
useEffect18(() => {
|
|
10038
|
+
if (state2.seen || !isVisible) return;
|
|
10039
|
+
const ready = defs.every(
|
|
10040
|
+
(def) => !def.Defaults || defaults3[def.id] !== void 0
|
|
10041
|
+
);
|
|
10042
|
+
if (!ready) return;
|
|
10043
|
+
const auto = defs.find((def) => defaults3[def.id]?.open);
|
|
10044
|
+
patchCompanionState(key, { seen: true, openId: auto?.id ?? null });
|
|
10045
|
+
}, [state2.seen, isVisible, defs, defaults3, key]);
|
|
10046
|
+
const active = defs.find((def) => def.id === state2.openId) ?? null;
|
|
10047
|
+
useEffect18(() => {
|
|
10048
|
+
if (!active) return;
|
|
10049
|
+
setMounted(
|
|
10050
|
+
(prev) => prev.has(active.id) ? prev : new Set(prev).add(active.id)
|
|
10051
|
+
);
|
|
10052
|
+
}, [active]);
|
|
10053
|
+
const activeDefaults = active ? defaults3[active.id] : void 0;
|
|
10054
|
+
const side = isMobile ? "bottom" : state2.side ?? activeDefaults?.side ?? "right";
|
|
10055
|
+
const baseSize = state2.size ?? activeDefaults?.size ?? (side === "bottom" ? DEFAULT_BOTTOM_SIZE : DEFAULT_SIDE_SIZE);
|
|
10056
|
+
const setSide = useCallback9(
|
|
10057
|
+
(next) => patchCompanionState(key, { side: next }),
|
|
10058
|
+
[key]
|
|
10059
|
+
);
|
|
10060
|
+
const close = useCallback9(
|
|
10061
|
+
() => patchCompanionState(key, { openId: null }),
|
|
10062
|
+
[key]
|
|
10063
|
+
);
|
|
10064
|
+
const startResize = (event) => {
|
|
10065
|
+
event.preventDefault();
|
|
10066
|
+
const root = rootRef.current;
|
|
10067
|
+
if (!root) return;
|
|
10068
|
+
const rect = root.getBoundingClientRect();
|
|
10069
|
+
const total = side === "bottom" ? rect.height : rect.width;
|
|
10070
|
+
const max = Math.max(MIN_SIZE, total - MIN_SIZE);
|
|
10071
|
+
setDragging(true);
|
|
10072
|
+
const move = (e) => {
|
|
10073
|
+
const raw = side === "right" ? rect.right - e.clientX : side === "left" ? e.clientX - rect.left : rect.bottom - e.clientY;
|
|
10074
|
+
patchCompanionState(key, {
|
|
10075
|
+
size: Math.round(Math.min(max, Math.max(MIN_SIZE, raw)))
|
|
10076
|
+
});
|
|
10077
|
+
};
|
|
10078
|
+
const up = () => {
|
|
10079
|
+
setDragging(false);
|
|
10080
|
+
window.removeEventListener("mousemove", move);
|
|
10081
|
+
window.removeEventListener("mouseup", up);
|
|
10082
|
+
};
|
|
10083
|
+
window.addEventListener("mousemove", move);
|
|
10084
|
+
window.addEventListener("mouseup", up);
|
|
10085
|
+
};
|
|
10086
|
+
const getHandle = useCallback9(
|
|
10087
|
+
() => tab.terminalRef?.current ?? null,
|
|
10088
|
+
[tab.terminalRef]
|
|
10089
|
+
);
|
|
10090
|
+
const sshHost = useMemo10(
|
|
10091
|
+
() => tab.host ? hostToSSHHost(tab.host) : void 0,
|
|
10092
|
+
[tab.host]
|
|
10093
|
+
);
|
|
10094
|
+
const showEdge = defs.filter((def) => defaults3[def.id]?.edgeButton !== false);
|
|
10095
|
+
const vertical = side === "bottom";
|
|
10096
|
+
const clamped = vertical ? Math.min(baseSize, 2e3) : baseSize;
|
|
10097
|
+
const paneStyle = isMobile ? { height: "55%" } : vertical ? { height: clamped } : { width: clamped };
|
|
10098
|
+
const SideIcon = sideIcon(side);
|
|
10099
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex h-full w-full min-h-0 min-w-0", children: [
|
|
10100
|
+
defs.map(
|
|
10101
|
+
(def) => def.Defaults ? /* @__PURE__ */ jsx13(DefaultsReader, { def, onValue: onDefaults }, def.id) : null
|
|
10102
|
+
),
|
|
10103
|
+
/* @__PURE__ */ jsxs6(
|
|
10104
|
+
"div",
|
|
10105
|
+
{
|
|
10106
|
+
ref: rootRef,
|
|
10107
|
+
className: cn(
|
|
10108
|
+
"relative flex flex-1 min-h-0 min-w-0",
|
|
10109
|
+
vertical ? "flex-col" : side === "left" ? "flex-row-reverse" : "flex-row"
|
|
10110
|
+
),
|
|
10111
|
+
children: [
|
|
10112
|
+
/* @__PURE__ */ jsx13("div", { className: "relative flex-1 min-h-0 min-w-0", children }),
|
|
10113
|
+
defs.map((def) => {
|
|
10114
|
+
if (!mounted.has(def.id)) return null;
|
|
10115
|
+
const open = active?.id === def.id;
|
|
10116
|
+
const Component = def.component;
|
|
10117
|
+
const Icon = def.icon;
|
|
10118
|
+
return /* @__PURE__ */ jsxs6(
|
|
10119
|
+
"div",
|
|
10120
|
+
{
|
|
10121
|
+
className: cn(
|
|
10122
|
+
"relative flex-shrink-0 flex-col min-h-0 min-w-0 bg-background border-border",
|
|
10123
|
+
open ? "flex" : "hidden",
|
|
10124
|
+
vertical ? "border-t" : side === "left" ? "border-r" : "border-l",
|
|
10125
|
+
isMobile && "absolute inset-x-0 bottom-0 z-20 shadow-lg"
|
|
10126
|
+
),
|
|
10127
|
+
style: paneStyle,
|
|
10128
|
+
children: [
|
|
10129
|
+
!isMobile && /* @__PURE__ */ jsx13(
|
|
10130
|
+
"div",
|
|
10131
|
+
{
|
|
10132
|
+
role: "separator",
|
|
10133
|
+
"aria-label": t("companion.resize"),
|
|
10134
|
+
onMouseDown: startResize,
|
|
10135
|
+
className: cn(
|
|
10136
|
+
"absolute z-10",
|
|
10137
|
+
vertical ? "inset-x-0 -top-1 h-2 cursor-row-resize" : side === "left" ? "inset-y-0 -right-1 w-2 cursor-col-resize" : "inset-y-0 -left-1 w-2 cursor-col-resize",
|
|
10138
|
+
dragging && "bg-primary/30"
|
|
10139
|
+
)
|
|
10140
|
+
}
|
|
10141
|
+
),
|
|
10142
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1.5 h-8 px-2 border-b border-border flex-shrink-0", children: [
|
|
10143
|
+
Icon && /* @__PURE__ */ jsx13(Icon, { className: "size-3.5 text-muted-foreground" }),
|
|
10144
|
+
/* @__PURE__ */ jsx13("span", { className: "text-xs font-medium truncate flex-1", children: def.titleKey ? t(def.titleKey) : def.id }),
|
|
10145
|
+
!isMobile && /* @__PURE__ */ jsx13(
|
|
10146
|
+
"button",
|
|
10147
|
+
{
|
|
10148
|
+
type: "button",
|
|
10149
|
+
className: "p-1 text-muted-foreground hover:text-foreground",
|
|
10150
|
+
title: t("companion.moveSide"),
|
|
10151
|
+
onClick: () => setSide(
|
|
10152
|
+
side === "right" ? "bottom" : side === "bottom" ? "left" : "right"
|
|
10153
|
+
),
|
|
10154
|
+
children: /* @__PURE__ */ jsx13(SideIcon, { className: "size-3.5" })
|
|
10155
|
+
}
|
|
10156
|
+
),
|
|
10157
|
+
/* @__PURE__ */ jsx13(
|
|
10158
|
+
"button",
|
|
10159
|
+
{
|
|
10160
|
+
type: "button",
|
|
10161
|
+
className: "p-1 text-muted-foreground hover:text-foreground",
|
|
10162
|
+
title: t("companion.close"),
|
|
10163
|
+
onClick: close,
|
|
10164
|
+
children: /* @__PURE__ */ jsx13(X, { className: "size-3.5" })
|
|
10165
|
+
}
|
|
10166
|
+
)
|
|
10167
|
+
] }),
|
|
10168
|
+
/* @__PURE__ */ jsx13("div", { className: "flex-1 min-h-0 min-w-0 overflow-hidden", children: /* @__PURE__ */ jsx13(
|
|
10169
|
+
Component,
|
|
10170
|
+
{
|
|
10171
|
+
tab,
|
|
10172
|
+
host: tab.host,
|
|
10173
|
+
sshHost,
|
|
10174
|
+
getHandle,
|
|
10175
|
+
side,
|
|
10176
|
+
isVisible: isVisible && open,
|
|
10177
|
+
close,
|
|
10178
|
+
setSide
|
|
10179
|
+
}
|
|
10180
|
+
) })
|
|
10181
|
+
]
|
|
10182
|
+
},
|
|
10183
|
+
def.id
|
|
10184
|
+
);
|
|
10185
|
+
})
|
|
10186
|
+
]
|
|
10187
|
+
}
|
|
10188
|
+
),
|
|
10189
|
+
showEdge.length > 0 && !isMobile && /* @__PURE__ */ jsx13("div", { className: "flex flex-col flex-shrink-0 w-6 items-center gap-1 pt-1 border-l border-border bg-background", children: showEdge.map((def) => {
|
|
10190
|
+
const Icon = def.icon ?? PanelRight;
|
|
10191
|
+
const open = active?.id === def.id;
|
|
10192
|
+
return /* @__PURE__ */ jsx13(
|
|
10193
|
+
"button",
|
|
10194
|
+
{
|
|
10195
|
+
type: "button",
|
|
10196
|
+
title: def.titleKey ? t(def.titleKey) : def.id,
|
|
10197
|
+
"aria-pressed": open,
|
|
10198
|
+
onClick: () => patchCompanionState(key, {
|
|
10199
|
+
seen: true,
|
|
10200
|
+
openId: open ? null : def.id
|
|
10201
|
+
}),
|
|
10202
|
+
className: cn(
|
|
10203
|
+
"p-1 text-muted-foreground hover:text-foreground",
|
|
10204
|
+
open && "text-foreground bg-accent"
|
|
10205
|
+
),
|
|
10206
|
+
children: /* @__PURE__ */ jsx13(Icon, { className: "size-3.5" })
|
|
10207
|
+
},
|
|
10208
|
+
def.id
|
|
10209
|
+
);
|
|
10210
|
+
}) })
|
|
10211
|
+
] });
|
|
10212
|
+
}
|
|
10213
|
+
|
|
10040
10214
|
// src/ui/shell/tabUtils.tsx
|
|
10041
|
-
import { jsx as
|
|
10215
|
+
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
10042
10216
|
var PluginsTab = lazy(
|
|
10043
|
-
() => import("./PluginsTab-
|
|
10217
|
+
() => import("./PluginsTab-YAGYRBIE.js").then((m) => ({ default: m.PluginsTab }))
|
|
10044
10218
|
);
|
|
10045
10219
|
function preloadTabSurface(type) {
|
|
10046
10220
|
const loader = getTabType(type)?.preload;
|
|
@@ -10053,37 +10227,37 @@ function EmptyState({
|
|
|
10053
10227
|
icon: Icon,
|
|
10054
10228
|
messageKey
|
|
10055
10229
|
}) {
|
|
10056
|
-
const { t } =
|
|
10057
|
-
return /* @__PURE__ */
|
|
10058
|
-
/* @__PURE__ */
|
|
10059
|
-
/* @__PURE__ */
|
|
10230
|
+
const { t } = useTranslation9();
|
|
10231
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-center justify-center flex-1 gap-3 p-6 text-center", children: [
|
|
10232
|
+
/* @__PURE__ */ jsx14("div", { className: "size-10 rounded-full bg-muted/40 flex items-center justify-center", children: /* @__PURE__ */ jsx14(Icon, { className: "size-5 text-muted-foreground/30" }) }),
|
|
10233
|
+
/* @__PURE__ */ jsx14("span", { className: "text-sm font-semibold text-muted-foreground/60", children: t(messageKey) })
|
|
10060
10234
|
] });
|
|
10061
10235
|
}
|
|
10062
10236
|
function TabChunkFallback() {
|
|
10063
|
-
return /* @__PURE__ */
|
|
10237
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex h-full w-full items-center justify-center bg-background", children: /* @__PURE__ */ jsx14("div", { className: "size-5 rounded-full border-2 border-muted-foreground/30 border-t-muted-foreground/70 animate-spin" }) });
|
|
10064
10238
|
}
|
|
10065
10239
|
function withTabSuspense(node) {
|
|
10066
|
-
return /* @__PURE__ */
|
|
10240
|
+
return /* @__PURE__ */ jsx14(Suspense, { fallback: /* @__PURE__ */ jsx14(TabChunkFallback, {}), children: node });
|
|
10067
10241
|
}
|
|
10068
10242
|
function PanelTabFrame({ children }) {
|
|
10069
|
-
return /* @__PURE__ */
|
|
10243
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex h-full w-full justify-center overflow-y-auto bg-background", children: /* @__PURE__ */ jsx14("div", { className: "flex flex-col flex-1 min-h-0 w-full max-w-5xl", children }) });
|
|
10070
10244
|
}
|
|
10071
10245
|
function tabIcon(type) {
|
|
10072
10246
|
switch (type) {
|
|
10073
10247
|
case "user-profile":
|
|
10074
10248
|
case "admin-settings":
|
|
10075
|
-
return /* @__PURE__ */
|
|
10249
|
+
return /* @__PURE__ */ jsx14(Settings, { className: "size-3.5" });
|
|
10076
10250
|
case "split-screen":
|
|
10077
|
-
return /* @__PURE__ */
|
|
10251
|
+
return /* @__PURE__ */ jsx14(LayoutPanelLeft, { className: "size-3.5" });
|
|
10078
10252
|
case "plugins":
|
|
10079
|
-
return /* @__PURE__ */
|
|
10253
|
+
return /* @__PURE__ */ jsx14(Puzzle, { className: "size-3.5" });
|
|
10080
10254
|
default: {
|
|
10081
10255
|
const Icon = getTabType(type)?.icon;
|
|
10082
|
-
return Icon ? /* @__PURE__ */
|
|
10256
|
+
return Icon ? /* @__PURE__ */ jsx14(Icon, { className: "size-3.5" }) : null;
|
|
10083
10257
|
}
|
|
10084
10258
|
}
|
|
10085
10259
|
}
|
|
10086
|
-
var RegisteredTab =
|
|
10260
|
+
var RegisteredTab = memo2(function RegisteredTab2({
|
|
10087
10261
|
def,
|
|
10088
10262
|
tab,
|
|
10089
10263
|
isVisible,
|
|
@@ -10093,7 +10267,7 @@ var RegisteredTab = memo(function RegisteredTab2({
|
|
|
10093
10267
|
}) {
|
|
10094
10268
|
const { host, label } = tab;
|
|
10095
10269
|
if (def.requiresHost && !host) {
|
|
10096
|
-
return /* @__PURE__ */
|
|
10270
|
+
return /* @__PURE__ */ jsx14(
|
|
10097
10271
|
EmptyState,
|
|
10098
10272
|
{
|
|
10099
10273
|
icon: Server,
|
|
@@ -10102,7 +10276,7 @@ var RegisteredTab = memo(function RegisteredTab2({
|
|
|
10102
10276
|
);
|
|
10103
10277
|
}
|
|
10104
10278
|
const Component = def.component;
|
|
10105
|
-
const content = /* @__PURE__ */
|
|
10279
|
+
const content = /* @__PURE__ */ jsx14(
|
|
10106
10280
|
Component,
|
|
10107
10281
|
{
|
|
10108
10282
|
tab,
|
|
@@ -10119,10 +10293,10 @@ var RegisteredTab = memo(function RegisteredTab2({
|
|
|
10119
10293
|
}
|
|
10120
10294
|
);
|
|
10121
10295
|
return withTabSuspense(
|
|
10122
|
-
def.panelFrame ? /* @__PURE__ */
|
|
10296
|
+
/* @__PURE__ */ jsx14(CompanionFrame, { tab, isVisible, children: def.panelFrame ? /* @__PURE__ */ jsx14(PanelTabFrame, { children: content }) : content })
|
|
10123
10297
|
);
|
|
10124
10298
|
});
|
|
10125
|
-
var PanelAsTab =
|
|
10299
|
+
var PanelAsTab = memo2(function PanelAsTab2({
|
|
10126
10300
|
panel,
|
|
10127
10301
|
isVisible,
|
|
10128
10302
|
targetTab,
|
|
@@ -10130,7 +10304,7 @@ var PanelAsTab = memo(function PanelAsTab2({
|
|
|
10130
10304
|
}) {
|
|
10131
10305
|
const Panel = panel.component;
|
|
10132
10306
|
return withTabSuspense(
|
|
10133
|
-
/* @__PURE__ */
|
|
10307
|
+
/* @__PURE__ */ jsx14(PanelTabFrame, { children: /* @__PURE__ */ jsx14(
|
|
10134
10308
|
Panel,
|
|
10135
10309
|
{
|
|
10136
10310
|
targetTab,
|
|
@@ -10155,7 +10329,7 @@ function renderTabContent(tab, context) {
|
|
|
10155
10329
|
case "split-screen":
|
|
10156
10330
|
return null;
|
|
10157
10331
|
case "plugins":
|
|
10158
|
-
return withTabSuspense(/* @__PURE__ */
|
|
10332
|
+
return withTabSuspense(/* @__PURE__ */ jsx14(PluginsTab, {}));
|
|
10159
10333
|
case "user-profile":
|
|
10160
10334
|
case "admin-settings":
|
|
10161
10335
|
return null;
|
|
@@ -10165,7 +10339,7 @@ function renderTabContent(tab, context) {
|
|
|
10165
10339
|
if (!def) {
|
|
10166
10340
|
const panel = getPanel(tab.type);
|
|
10167
10341
|
if (panel) {
|
|
10168
|
-
return /* @__PURE__ */
|
|
10342
|
+
return /* @__PURE__ */ jsx14(
|
|
10169
10343
|
PanelAsTab,
|
|
10170
10344
|
{
|
|
10171
10345
|
panel,
|
|
@@ -10175,9 +10349,9 @@ function renderTabContent(tab, context) {
|
|
|
10175
10349
|
}
|
|
10176
10350
|
);
|
|
10177
10351
|
}
|
|
10178
|
-
return /* @__PURE__ */
|
|
10352
|
+
return /* @__PURE__ */ jsx14(PluginViewPlaceholder, { kind: "tab", viewId: tab.type });
|
|
10179
10353
|
}
|
|
10180
|
-
return /* @__PURE__ */
|
|
10354
|
+
return /* @__PURE__ */ jsx14(
|
|
10181
10355
|
RegisteredTab,
|
|
10182
10356
|
{
|
|
10183
10357
|
def,
|
|
@@ -10225,6 +10399,7 @@ export {
|
|
|
10225
10399
|
remScale,
|
|
10226
10400
|
useIsMobile,
|
|
10227
10401
|
getLoginMethods,
|
|
10402
|
+
getRememberDeviceAllowed,
|
|
10228
10403
|
submitLoginMethod,
|
|
10229
10404
|
startLoginRedirect,
|
|
10230
10405
|
verifySecondFactor,
|
|
@@ -10244,20 +10419,6 @@ export {
|
|
|
10244
10419
|
changeAppLanguage,
|
|
10245
10420
|
rememberLoginLanguage,
|
|
10246
10421
|
i18n_default,
|
|
10247
|
-
probeServer,
|
|
10248
|
-
getLinkPreview,
|
|
10249
|
-
completeLink,
|
|
10250
|
-
reloginLink,
|
|
10251
|
-
unlinkServer,
|
|
10252
|
-
syncNow,
|
|
10253
|
-
updateSyncSettings,
|
|
10254
|
-
getSyncConflicts,
|
|
10255
|
-
settleSyncConflict,
|
|
10256
|
-
getSyncErrors,
|
|
10257
|
-
retrySyncErrors,
|
|
10258
|
-
setSyncStatus,
|
|
10259
|
-
refreshSyncStatus,
|
|
10260
|
-
useSyncStatus,
|
|
10261
10422
|
getPanel,
|
|
10262
10423
|
listPanels,
|
|
10263
10424
|
usePanels,
|