mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 22:25:24 +00:00
feat: wire remote-desktop plugin into core and rename i18n keys
Repoints core consumers (dispatcher, collab, session-sharing, tab utils) at the plugin, adds isTabTypeAvailable gating for rdp/vnc/ telnet, widens hostCapability to accept an array, and renames the guacamole i18n namespace to remoteDesktop.
This commit is contained in:
1 parent
c6bcfdb80d
commit
76b2e5739a
41 files changed
+361
-686
No files matched your search
@@ -62,6 +62,12 @@
|
||||
* do, verifies host keys via SSHHostKeyVerifier, and streams its discovery
|
||||
* progress as server-sent events. Neither the worker's 13-field read-only
|
||||
* ctx.hosts nor its single-postMessage-reply ctx.http.route can support that.
|
||||
*
|
||||
* remote-desktop is here for the same reason ssh-terminal is: it owns a
|
||||
* WebSocket server (guacamole-lite, port 30008) and its
|
||||
* /connect-host/:hostId route does multi-step credential/tunnel resolution
|
||||
* (SSH jump-host tunnels, a macOS VNC compatibility proxy) using raw
|
||||
* net.Socket plumbing that cannot cross a structured-clone boundary.
|
||||
*/
|
||||
export const FIRST_PARTY_PLUGIN_IDS: ReadonlySet<string> = new Set([
|
||||
"ssh-terminal",
|
||||
@@ -69,6 +75,7 @@ export const FIRST_PARTY_PLUGIN_IDS: ReadonlySet<string> = new Set([
|
||||
"host-metrics",
|
||||
"ai",
|
||||
"proxmox",
|
||||
"remote-desktop",
|
||||
]);
|
||||
|
||||
export const TRANSPORT_OWNER_CAPABILITY = "process:transport-owner";
|
||||
|
||||
@@ -128,7 +128,7 @@ export interface PluginManifest {
|
||||
icon: string;
|
||||
openFrom: string[];
|
||||
}>;
|
||||
hostCapability?: { key: string; labelKey: string; editorTab: string };
|
||||
hostCapability?: HostCapabilityContribution | HostCapabilityContribution[];
|
||||
permissionGroup?: {
|
||||
group: string;
|
||||
permissions: string[];
|
||||
@@ -161,6 +161,19 @@ export interface PluginManifest {
|
||||
sidecars: Array<{ id: string; binary: string }>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A host-level checkbox this plugin contributes to the host editor (e.g.
|
||||
* "Enable RDP"), backed by an existing boolean column on the host record.
|
||||
* Most plugins declare one; a plugin covering several independent protocols
|
||||
* on the same host (rdp/vnc/telnet) declares several -- see
|
||||
* contributes.hostCapability, which accepts either shape.
|
||||
*/
|
||||
export interface HostCapabilityContribution {
|
||||
key: string;
|
||||
labelKey: string;
|
||||
editorTab: string;
|
||||
}
|
||||
|
||||
export interface PluginServiceProvide {
|
||||
service: string;
|
||||
version: string;
|
||||
@@ -540,15 +553,26 @@ function validateContributes(contributes: Record<string, unknown>): string[] {
|
||||
}
|
||||
|
||||
if ("hostCapability" in contributes) {
|
||||
const hostCapability = (contributes.hostCapability ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
for (const field of ["key", "labelKey", "editorTab"]) {
|
||||
if (!(field in hostCapability)) {
|
||||
errors.push(`contributes.hostCapability.${field} is required`);
|
||||
const raw = contributes.hostCapability;
|
||||
const entries = Array.isArray(raw) ? raw : [raw];
|
||||
const seenKeys = new Set<string>();
|
||||
entries.forEach((entry, index) => {
|
||||
const hc = (entry ?? {}) as Record<string, unknown>;
|
||||
const prefix = Array.isArray(raw)
|
||||
? `contributes.hostCapability[${index}]`
|
||||
: "contributes.hostCapability";
|
||||
for (const field of ["key", "labelKey", "editorTab"]) {
|
||||
if (!(field in hc)) {
|
||||
errors.push(`${prefix}.${field} is required`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof hc.key === "string") {
|
||||
if (seenKeys.has(hc.key)) {
|
||||
errors.push(`${prefix}.key is a duplicate: "${hc.key}"`);
|
||||
}
|
||||
seenKeys.add(hc.key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ("permissionGroup" in contributes) {
|
||||
|
||||
Reference in new issue
Block a user