hermes-sshx-link/dashboard/dist/index.js

140 lines
4.1 KiB
JavaScript
Raw Normal View History

(function () {
"use strict";
const SDK = window.__HERMES_PLUGIN_SDK__;
const { React } = SDK;
const { useState, useEffect, useCallback } = SDK.hooks;
const { Card, CardHeader, CardTitle, CardContent, Button } = SDK.components;
// Use native fetch with session token header for remote dashboard
function getSessionToken() {
return window.__HERMES_SESSION_TOKEN__ || "";
}
async function apiFetch(path) {
const res = await fetch(path, {
credentials: "include",
headers: { "x-hermes-session-token": getSessionToken() }
});
if (!res.ok) {
const text = await res.text();
throw new Error("API error " + res.status + ": " + text.slice(0, 100));
}
return res.json();
}
async function apiPost(path) {
const res = await fetch(path, {
method: "POST",
credentials: "include",
headers: { "x-hermes-session-token": getSessionToken() }
});
if (!res.ok) {
const text = await res.text();
throw new Error("API error " + res.status + ": " + text.slice(0, 100));
}
return res.json();
}
function SSHXPage() {
const [link, setLink] = useState(null);
const [status, setStatus] = useState("idle");
const [error, setError] = useState(null);
const startSSHX = useCallback(async function () {
setStatus("loading");
setError(null);
try {
const res = await apiFetch("/api/plugins/sshx-link/start");
if (res.link) {
setLink(res.link);
setStatus("running");
} else {
setError(res.message || "No link returned");
setStatus("error");
}
} catch (err) {
setError(err.message || "Failed to start sshx");
setStatus("error");
}
}, []);
const stopSSHX = useCallback(async function () {
try {
await apiPost("/api/plugins/sshx-link/stop");
setLink(null);
setStatus("idle");
} catch (err) {
setError(err.message);
}
}, []);
const checkStatus = useCallback(async function () {
try {
const res = await apiFetch("/api/plugins/sshx-link/status");
if (res.status === "running" && res.link) {
setLink(res.link);
setStatus("running");
}
} catch (_) {}
}, []);
useEffect(function () {
checkStatus();
}, [checkStatus]);
if (status === "running" && link) {
return React.createElement(Card, null,
React.createElement(CardHeader, null,
React.createElement(CardTitle, null, "SSHX Shared Terminal")
),
React.createElement(CardContent, null,
React.createElement("p", {
className: "text-sm text-green-500",
style: { fontWeight: 600, marginBottom: "0.5rem" }
}, "Running"),
React.createElement("a", {
href: link,
target: "_blank",
rel: "noopener noreferrer",
style: {
color: "#60a5fa",
fontSize: "1.1rem",
wordBreak: "break-all",
textDecoration: "underline"
}
}, link),
React.createElement("div", { style: { marginTop: "1rem" } },
React.createElement(Button, {
onClick: stopSSHX,
variant: "destructive"
}, "Stop")
)
)
);
}
return React.createElement(Card, null,
React.createElement(CardHeader, null,
React.createElement(CardTitle, null, "SSHX Shared Terminal")
),
React.createElement(CardContent, null,
React.createElement("p", {
className: "text-sm text-muted-foreground",
style: { marginBottom: "1rem" }
}, "Start a shared terminal session. Others can join via the link."),
error && React.createElement("p", {
className: "text-sm text-red-500",
style: { marginBottom: "1rem" }
}, "Error: " + error),
React.createElement(Button, {
onClick: startSSHX,
disabled: status === "loading"
}, status === "loading" ? "Starting..." : "Start SSHX")
)
);
}
window.__HERMES_PLUGINS__.register("sshx-link", SSHXPage);
})();