@elizaos/plugin-screenshare 2.0.3-beta.6 → 2.0.3-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/components/ScreenshareSpatialView.d.ts +61 -0
  2. package/dist/components/ScreenshareSpatialView.d.ts.map +1 -0
  3. package/dist/components/ScreenshareSpatialView.js +206 -0
  4. package/dist/components/ScreenshareSpatialView.js.map +1 -0
  5. package/dist/components/ScreenshareView.d.ts +13 -0
  6. package/dist/components/ScreenshareView.d.ts.map +1 -0
  7. package/dist/components/ScreenshareView.js +263 -0
  8. package/dist/components/ScreenshareView.js.map +1 -0
  9. package/dist/index.d.ts +9 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +58 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/register-terminal-view.d.ts +15 -0
  14. package/dist/register-terminal-view.d.ts.map +1 -0
  15. package/dist/register-terminal-view.js +27 -0
  16. package/dist/register-terminal-view.js.map +1 -0
  17. package/dist/routes.d.ts +8 -0
  18. package/dist/routes.d.ts.map +1 -0
  19. package/dist/routes.js +639 -0
  20. package/dist/routes.js.map +1 -0
  21. package/dist/session-store.d.ts +44 -0
  22. package/dist/session-store.d.ts.map +1 -0
  23. package/dist/session-store.js +200 -0
  24. package/dist/session-store.js.map +1 -0
  25. package/dist/ui/ScreenshareOperatorSurface.d.ts +5 -0
  26. package/dist/ui/ScreenshareOperatorSurface.d.ts.map +1 -0
  27. package/dist/ui/ScreenshareOperatorSurface.helpers.d.ts +40 -0
  28. package/dist/ui/ScreenshareOperatorSurface.helpers.d.ts.map +1 -0
  29. package/dist/ui/ScreenshareOperatorSurface.helpers.js +47 -0
  30. package/dist/ui/ScreenshareOperatorSurface.helpers.js.map +1 -0
  31. package/dist/ui/ScreenshareOperatorSurface.interact.d.ts +2 -0
  32. package/dist/ui/ScreenshareOperatorSurface.interact.d.ts.map +1 -0
  33. package/dist/ui/ScreenshareOperatorSurface.interact.js +100 -0
  34. package/dist/ui/ScreenshareOperatorSurface.interact.js.map +1 -0
  35. package/dist/ui/ScreenshareOperatorSurface.js +746 -0
  36. package/dist/ui/ScreenshareOperatorSurface.js.map +1 -0
  37. package/dist/ui/index.d.ts +3 -0
  38. package/dist/ui/index.d.ts.map +1 -0
  39. package/dist/ui/index.js +10 -0
  40. package/dist/ui/index.js.map +1 -0
  41. package/dist/ui/screenshare-view-bundle.d.ts +3 -0
  42. package/dist/ui/screenshare-view-bundle.d.ts.map +1 -0
  43. package/dist/ui/screenshare-view-bundle.js +7 -0
  44. package/dist/ui/screenshare-view-bundle.js.map +1 -0
  45. package/dist/views/bundle.js +507 -0
  46. package/dist/views/bundle.js.map +1 -0
  47. package/package.json +8 -8
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/ScreenshareOperatorSurface.tsx"],"sourcesContent":["import {\n type AgentElementRole,\n type AppOperatorSurfaceProps,\n Button,\n type ButtonProps,\n client,\n Input,\n type InputProps,\n SurfaceEmptyState,\n SurfaceSection,\n selectLatestRunForApp,\n useAppSelector,\n} from \"@elizaos/ui\";\nimport { useAgentElement } from \"@elizaos/ui/agent-surface\";\nimport {\n CheckCircle2,\n Copy,\n ExternalLink,\n type LucideIcon,\n MonitorUp,\n PlugZap,\n Power,\n RefreshCw,\n XCircle,\n} from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport {\n buildViewerUrl,\n type CapabilitiesResponse,\n fetchJson,\n loadScreenshareTuiState,\n type PublicSession,\n type StartSessionResponse,\n} from \"./ScreenshareOperatorSurface.helpers\";\n\nconst APP_NAME = \"@elizaos/plugin-screenshare\";\n\nfunction parseViewerSession(\n viewerUrl: string | null | undefined,\n): { sessionId: string; token: string } | null {\n if (!viewerUrl) {\n return null;\n }\n try {\n const url = new URL(viewerUrl, window.location.origin);\n const sessionId = url.searchParams.get(\"sessionId\")?.trim();\n const token = url.searchParams.get(\"token\")?.trim();\n return sessionId && token ? { sessionId, token } : null;\n } catch {\n return null;\n }\n}\n\nfunction formatTime(value: string | null): string {\n if (!value) {\n return \"Not yet\";\n }\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? \"Not yet\" : date.toLocaleTimeString();\n}\n\nfunction ScreenshareMetric({\n icon: Icon,\n label,\n value,\n active,\n}: {\n icon: LucideIcon;\n label: string;\n value: string | number;\n active?: boolean;\n}) {\n return (\n <div\n className=\"flex min-h-16 flex-col items-center justify-center gap-1.5 px-3 py-2\"\n title={label}\n role=\"status\"\n aria-label={`${label}: ${value}`}\n >\n <div className=\"flex items-center gap-1.5\">\n <span\n className={`h-1.5 w-1.5 shrink-0 rounded-full ${\n active ? \"bg-accent\" : \"bg-muted/40\"\n }`}\n aria-hidden\n />\n <Icon\n className={`h-3.5 w-3.5 ${active ? \"text-accent\" : \"text-muted\"}`}\n />\n </div>\n <span\n className={`truncate text-sm font-semibold ${\n active ? \"text-txt\" : \"text-muted-strong\"\n }`}\n >\n {value}\n </span>\n </div>\n );\n}\n\nfunction ScreenshareActionButton({\n agentId,\n label,\n group,\n description,\n status,\n ...buttonProps\n}: ButtonProps & {\n agentId: string;\n label: string;\n group: string;\n description: string;\n status?: \"active\" | \"inactive\";\n}) {\n const { ref, agentProps } = useAgentElement<HTMLButtonElement>({\n id: agentId,\n role: \"button\",\n label,\n group,\n description,\n ...(status ? { status } : {}),\n });\n return (\n <Button ref={ref} aria-label={label} {...agentProps} {...buttonProps} />\n );\n}\n\nfunction ScreenshareField({\n agentId,\n label,\n group,\n description,\n role = \"text-input\",\n ...inputProps\n}: InputProps & {\n agentId: string;\n label: string;\n group: string;\n description: string;\n role?: AgentElementRole;\n}) {\n const { ref, agentProps } = useAgentElement<HTMLInputElement>({\n id: agentId,\n role,\n label,\n group,\n description,\n fillable: !inputProps.readOnly,\n });\n return <Input ref={ref} aria-label={label} {...agentProps} {...inputProps} />;\n}\n\nexport function ScreenshareOperatorSurface({\n appName,\n focus = \"all\",\n}: AppOperatorSurfaceProps) {\n const appRuns = useAppSelector((s) => s.appRuns);\n const setActionNotice = useAppSelector((s) => s.setActionNotice);\n const { run } = useMemo(\n () => selectLatestRunForApp(appName || APP_NAME, appRuns),\n [appName, appRuns],\n );\n const launchedSession = useMemo(\n () => parseViewerSession(run?.viewer?.url),\n [run?.viewer?.url],\n );\n\n const [capabilities, setCapabilities] = useState<CapabilitiesResponse | null>(\n null,\n );\n const [hostSession, setHostSession] = useState<PublicSession | null>(null);\n const [hostToken, setHostToken] = useState<string>(\n launchedSession?.token ?? \"\",\n );\n const [remoteBase, setRemoteBase] = useState(\"\");\n const [remoteSessionId, setRemoteSessionId] = useState(\"\");\n const [remoteToken, setRemoteToken] = useState(\"\");\n const [busy, setBusy] = useState<string | null>(null);\n\n const loadCapabilities = useCallback(async () => {\n const next = await fetchJson<CapabilitiesResponse>(\n \"/api/apps/screenshare/capabilities\",\n );\n setCapabilities(next);\n }, []);\n\n const loadLaunchedSession = useCallback(async () => {\n if (!launchedSession) {\n return;\n }\n setHostToken(launchedSession.token);\n const next = await fetchJson<{ session: PublicSession }>(\n `/api/apps/screenshare/session/${encodeURIComponent(\n launchedSession.sessionId,\n )}?token=${encodeURIComponent(launchedSession.token)}`,\n );\n setHostSession(next.session);\n }, [launchedSession]);\n\n useEffect(() => {\n void loadCapabilities().catch((error) => {\n setActionNotice(\n error instanceof Error ? error.message : \"Failed to load capabilities.\",\n \"error\",\n 3200,\n );\n });\n }, [loadCapabilities, setActionNotice]);\n\n useEffect(() => {\n void loadLaunchedSession().catch((error) => {\n setActionNotice(\n error instanceof Error\n ? error.message\n : \"Failed to load screen share session.\",\n \"error\",\n 3200,\n );\n });\n }, [loadLaunchedSession, setActionNotice]);\n\n const startHostSession = useCallback(async () => {\n setBusy(\"start\");\n try {\n const response = await fetchJson<StartSessionResponse>(\n \"/api/apps/screenshare/session\",\n {\n method: \"POST\",\n body: JSON.stringify({ label: \"This machine\" }),\n },\n );\n setHostSession(response.session);\n setHostToken(response.token);\n setActionNotice(\"Screen share session started.\", \"success\", 2400);\n } catch (error) {\n setActionNotice(\n error instanceof Error ? error.message : \"Failed to start session.\",\n \"error\",\n 3600,\n );\n } finally {\n setBusy(null);\n }\n }, [setActionNotice]);\n\n const stopHostSession = useCallback(async () => {\n if (!hostSession || !hostToken) {\n return;\n }\n setBusy(\"stop\");\n try {\n const response = await fetchJson<{ session: PublicSession }>(\n `/api/apps/screenshare/session/${encodeURIComponent(hostSession.id)}/stop`,\n {\n method: \"POST\",\n body: JSON.stringify({ token: hostToken }),\n headers: { \"X-Screenshare-Token\": hostToken },\n },\n );\n setHostSession(response.session);\n setActionNotice(\"Screen share session stopped.\", \"success\", 2400);\n } catch (error) {\n setActionNotice(\n error instanceof Error ? error.message : \"Failed to stop session.\",\n \"error\",\n 3600,\n );\n } finally {\n setBusy(null);\n }\n }, [hostSession, hostToken, setActionNotice]);\n\n const copyHostDetails = useCallback(async () => {\n if (!hostSession || !hostToken) {\n return;\n }\n const url = buildViewerUrl({\n sessionId: hostSession.id,\n token: hostToken,\n });\n try {\n await navigator.clipboard.writeText(\n JSON.stringify(\n {\n serverUrl: client.getBaseUrl() || window.location.origin,\n sessionId: hostSession.id,\n token: hostToken,\n viewerUrl: url,\n },\n null,\n 2,\n ),\n );\n setActionNotice(\"Screen share details copied.\", \"success\", 1800);\n } catch (error) {\n setActionNotice(\n error instanceof Error ? error.message : \"Clipboard write failed.\",\n \"error\",\n 3200,\n );\n }\n }, [hostSession, hostToken, setActionNotice]);\n\n const openViewer = useCallback((url: string) => {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n }, []);\n\n const hostViewerUrl =\n hostSession && hostToken\n ? buildViewerUrl({ sessionId: hostSession.id, token: hostToken })\n : null;\n const remoteViewerUrl =\n remoteSessionId.trim() && remoteToken.trim()\n ? buildViewerUrl({\n baseUrl: remoteBase,\n sessionId: remoteSessionId.trim(),\n token: remoteToken.trim(),\n })\n : null;\n\n if (focus === \"chat\") {\n return <SurfaceEmptyState title=\"Screen Share\" body=\"\" />;\n }\n\n return (\n <section className=\"flex min-h-0 flex-col gap-3 p-3\">\n <SurfaceSection title=\"Host\">\n <div className=\"grid grid-cols-3 gap-2\">\n <ScreenshareMetric\n icon={MonitorUp}\n label=\"Session\"\n value={hostSession?.status ?? \"idle\"}\n active={hostSession?.status === \"active\"}\n />\n <ScreenshareMetric\n icon={PlugZap}\n label=\"Platform\"\n value={capabilities?.platform ?? hostSession?.platform ?? \"desktop\"}\n active={Boolean(capabilities?.platform || hostSession?.platform)}\n />\n <ScreenshareMetric\n icon={\n capabilities?.capabilities.headfulGui?.available\n ? CheckCircle2\n : XCircle\n }\n label=\"GUI\"\n value=\"GUI\"\n active={capabilities?.capabilities.headfulGui?.available}\n />\n </div>\n\n <div className=\"mt-3 flex flex-col gap-2\">\n <ScreenshareActionButton\n agentId=\"action-start-host\"\n label={\n hostSession?.status === \"active\"\n ? \"Rotate host session\"\n : \"Start host session\"\n }\n group=\"host\"\n description=\"Start or rotate the screen share session for this machine\"\n type=\"button\"\n size=\"sm\"\n variant=\"default\"\n className=\"h-10 w-full justify-center gap-2\"\n onClick={() => void startHostSession()}\n disabled={busy === \"start\"}\n >\n <MonitorUp className=\"h-4 w-4\" />\n {hostSession?.status === \"active\"\n ? \"Rotate session\"\n : \"Start session\"}\n </ScreenshareActionButton>\n <div className=\"grid grid-cols-3 gap-2\">\n <ScreenshareActionButton\n agentId=\"action-open-host-viewer\"\n label=\"Open host viewer\"\n group=\"host\"\n description=\"Open the viewer for the host screen share session\"\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"h-9 justify-center gap-1.5\"\n onClick={() => hostViewerUrl && openViewer(hostViewerUrl)}\n disabled={!hostViewerUrl}\n >\n <ExternalLink className=\"h-4 w-4\" />\n Open\n </ScreenshareActionButton>\n <ScreenshareActionButton\n agentId=\"action-copy-host-details\"\n label=\"Copy host details\"\n group=\"host\"\n description=\"Copy the host session connection details to the clipboard\"\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"h-9 justify-center gap-1.5\"\n onClick={() => void copyHostDetails()}\n disabled={!hostSession || !hostToken}\n >\n <Copy className=\"h-4 w-4\" />\n Copy\n </ScreenshareActionButton>\n <ScreenshareActionButton\n agentId=\"action-stop-host\"\n label=\"Stop host session\"\n group=\"host\"\n description=\"Stop the active host screen share session\"\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"h-9 justify-center gap-1.5\"\n onClick={() => void stopHostSession()}\n disabled={hostSession?.status !== \"active\"}\n >\n <Power className=\"h-4 w-4\" />\n Stop\n </ScreenshareActionButton>\n </div>\n </div>\n\n {hostSession ? (\n <div className=\"mt-3 grid grid-cols-2 gap-2\">\n <ScreenshareMetric\n icon={MonitorUp}\n label=\"Frames\"\n value={hostSession.frameCount}\n active={hostSession.frameCount > 0}\n />\n <ScreenshareMetric\n icon={PlugZap}\n label=\"Inputs\"\n value={hostSession.inputCount}\n active={hostSession.inputCount > 0}\n />\n <ScreenshareMetric\n icon={RefreshCw}\n label=\"Last frame\"\n value={formatTime(hostSession.lastFrameAt)}\n active={hostSession.lastFrameAt !== null}\n />\n <ScreenshareMetric\n icon={Power}\n label=\"Last input\"\n value={formatTime(hostSession.lastInputAt)}\n active={hostSession.lastInputAt !== null}\n />\n </div>\n ) : null}\n </SurfaceSection>\n\n <SurfaceSection title=\"Connect\">\n <div className=\"grid gap-2\">\n <ScreenshareField\n agentId=\"input-remote-base\"\n label=\"Remote server URL\"\n group=\"connect\"\n description=\"Server URL of the remote machine to connect to\"\n value={remoteBase}\n onChange={(event) => setRemoteBase(event.target.value)}\n placeholder=\"Server URL\"\n className=\"h-9 border-0 bg-transparent text-xs\"\n />\n <ScreenshareField\n agentId=\"input-remote-session\"\n label=\"Remote session id\"\n group=\"connect\"\n description=\"Session id of the remote screen share to connect to\"\n value={remoteSessionId}\n onChange={(event) => setRemoteSessionId(event.target.value)}\n placeholder=\"Session\"\n className=\"h-9 border-0 bg-transparent text-xs\"\n />\n <ScreenshareField\n agentId=\"input-remote-token\"\n label=\"Remote session token\"\n group=\"connect\"\n description=\"Token of the remote screen share to connect to\"\n value={remoteToken}\n onChange={(event) => setRemoteToken(event.target.value)}\n placeholder=\"Token\"\n className=\"h-9 border-0 bg-transparent text-xs\"\n />\n </div>\n <div className=\"mt-3 flex gap-2\">\n <ScreenshareActionButton\n agentId=\"action-connect-remote\"\n label=\"Connect to remote\"\n group=\"connect\"\n description=\"Open the viewer for the entered remote screen share\"\n type=\"button\"\n size=\"sm\"\n variant={remoteViewerUrl ? \"default\" : \"outline\"}\n className=\"h-10 flex-1 justify-center gap-2\"\n onClick={() => remoteViewerUrl && openViewer(remoteViewerUrl)}\n disabled={!remoteViewerUrl}\n >\n <PlugZap className=\"h-4 w-4\" />\n Connect\n </ScreenshareActionButton>\n <ScreenshareActionButton\n agentId=\"action-refresh-capabilities\"\n label=\"Refresh capabilities\"\n group=\"connect\"\n description=\"Reload the host screen share capabilities\"\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"h-10 w-10 justify-center gap-2 px-0\"\n onClick={() => void loadCapabilities()}\n title=\"Refresh capabilities\"\n >\n <RefreshCw className=\"h-4 w-4\" />\n </ScreenshareActionButton>\n </div>\n </SurfaceSection>\n\n {capabilities ? (\n <SurfaceSection title=\"Capabilities\">\n <div className=\"grid grid-cols-3 gap-2\">\n {Object.entries(capabilities.capabilities).map(\n ([name, capability]) => (\n <div\n key={name}\n className=\"flex min-h-14 items-center justify-center gap-2 px-3 py-2\"\n title={`${name}: ${capability.tool}`}\n >\n {capability.available ? (\n <CheckCircle2 className=\"h-4 w-4 text-accent\" />\n ) : (\n <XCircle className=\"h-4 w-4 text-muted\" />\n )}\n <span\n className={\n capability.available\n ? \"truncate text-xs font-semibold text-txt\"\n : \"truncate text-xs font-semibold text-muted-strong\"\n }\n >\n {name}\n </span>\n </div>\n ),\n )}\n </div>\n </SurfaceSection>\n ) : null}\n </section>\n );\n}\n\nexport function ScreenshareTuiView() {\n const [state, setState] = useState<Awaited<\n ReturnType<typeof loadScreenshareTuiState>\n > | null>(null);\n const [loading, setLoading] = useState(true);\n const [lastAction, setLastAction] = useState(\"boot\");\n const [error, setError] = useState<string | null>(null);\n\n const refreshElement = useAgentElement<HTMLButtonElement>({\n id: \"tui-refresh-sessions\",\n role: \"button\",\n label: \"Refresh sessions\",\n group: \"tui-sessions\",\n description: \"Reload the screen share sessions and capabilities\",\n status: loading ? \"loading\" : \"idle\",\n });\n\n const refresh = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const next = await loadScreenshareTuiState();\n setState(next);\n setLastAction(\"refresh\");\n } catch (caught) {\n setState(null);\n setError(\n caught instanceof Error\n ? caught.message\n : \"Screen share refresh failed\",\n );\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const activeSessions =\n state?.sessions.sessions.filter((session) => session.status === \"active\") ??\n [];\n const viewState = {\n viewType: \"tui\",\n viewId: \"screenshare\",\n platform: state?.capabilities.platform ?? null,\n sessionCount: state?.sessions.sessions.length ?? 0,\n activeSessionCount: activeSessions.length,\n capabilities: state\n ? Object.fromEntries(\n Object.entries(state.capabilities.capabilities).map(\n ([name, capability]) => [name, capability.available],\n ),\n )\n : {},\n loading,\n lastAction,\n error,\n };\n\n return (\n <div\n data-view-state={JSON.stringify(viewState)}\n style={{\n minHeight: \"100vh\",\n background: \"#020617\",\n color: \"#cbd5e1\",\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace',\n padding: 20,\n }}\n >\n <div\n data-status={loading ? \"loading\" : \"ready\"}\n style={{ color: \"#94a3b8\", marginBottom: 16 }}\n >\n {loading ? \"loading\" : (state?.capabilities.platform ?? \"unknown\")} |{\" \"}\n {activeSessions.length} active sessions | {lastAction}\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr\",\n gap: 16,\n }}\n >\n <section\n aria-label=\"Screen share sessions\"\n style={{\n padding: \"8px 0\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n marginBottom: 10,\n }}\n >\n <strong style={{ color: \"#e2e8f0\" }}>sessions</strong>\n <button\n ref={refreshElement.ref}\n type=\"button\"\n aria-label=\"Refresh sessions\"\n onClick={() => void refresh()}\n disabled={loading}\n style={{\n background: \"transparent\",\n color: \"#a7f3d0\",\n border: 0,\n padding: \"4px 8px\",\n cursor: loading ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n }}\n {...refreshElement.agentProps}\n >\n refresh\n </button>\n </div>\n {error && <div style={{ color: \"#fca5a5\" }}>{error}</div>}\n {(state?.sessions.sessions ?? []).map((session) => (\n <div\n key={session.id}\n style={{\n padding: \"8px 0\",\n }}\n >\n <div style={{ color: \"#e2e8f0\" }}>\n {session.id} / {session.status}\n </div>\n <div style={{ color: \"#94a3b8\" }}>\n {session.label} frames {session.frameCount} inputs{\" \"}\n {session.inputCount}\n </div>\n <div style={{ color: \"#64748b\" }}>\n last frame {formatTime(session.lastFrameAt)} / last input{\" \"}\n {formatTime(session.lastInputAt)}\n </div>\n </div>\n ))}\n </section>\n\n <section\n aria-label=\"Screen share capabilities\"\n style={{\n padding: \"8px 0\",\n }}\n >\n <strong style={{ color: \"#e2e8f0\" }}>capabilities</strong>\n <div style={{ color: \"#64748b\", margin: \"6px 0 14px\" }}>\n {\n Object.values(state?.capabilities.capabilities ?? {}).filter(\n (capability) => capability.available,\n ).length\n }{\" \"}\n live / {state?.sessions.sessions.length ?? 0} sessions\n </div>\n <div>\n <span style={{ color: \"#64748b\" }}>platform</span>{\" \"}\n {state?.capabilities.platform ?? \"unknown\"}\n </div>\n {Object.entries(state?.capabilities.capabilities ?? {}).map(\n ([name, capability]) => (\n <div key={name} style={{ padding: \"6px 0\" }}>\n <span\n style={{\n color: capability.available ? \"#a7f3d0\" : \"#fca5a5\",\n }}\n >\n {capability.available ? \"ok\" : \"off\"}\n </span>{\" \"}\n {name} via {capability.tool}\n </div>\n ),\n )}\n </section>\n </div>\n </div>\n );\n}\n\n// The bundled view (GUI + XR + TUI) is the unified ScreenshareView spatial\n// source. This operator surface remains the in-process dashboard mounted via\n// the operator-surface registry; re-surface ScreenshareView here so callers of\n// the ui barrel reach the one bundled view component.\nexport { ScreenshareView } from \"../components/ScreenshareView.js\";\n"],"mappings":"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","names":[]}
@@ -0,0 +1,3 @@
1
+ import { ScreenshareOperatorSurface } from "./ScreenshareOperatorSurface";
2
+ export { ScreenshareOperatorSurface };
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAO1E,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { registerOperatorSurface } from "@elizaos/ui";
2
+ import { ScreenshareOperatorSurface } from "./ScreenshareOperatorSurface.js";
3
+ registerOperatorSurface(
4
+ "@elizaos/plugin-screenshare",
5
+ ScreenshareOperatorSurface
6
+ );
7
+ export {
8
+ ScreenshareOperatorSurface
9
+ };
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/index.ts"],"sourcesContent":["import { registerOperatorSurface } from \"@elizaos/ui\";\nimport { ScreenshareOperatorSurface } from \"./ScreenshareOperatorSurface.js\";\n\nregisterOperatorSurface(\n \"@elizaos/plugin-screenshare\",\n ScreenshareOperatorSurface,\n);\n\nexport { ScreenshareOperatorSurface };\n"],"mappings":"AAAA,SAAS,+BAA+B;AACxC,SAAS,kCAAkC;AAE3C;AAAA,EACE;AAAA,EACA;AACF;","names":[]}
@@ -0,0 +1,3 @@
1
+ export { interact } from "./ScreenshareOperatorSurface.interact";
2
+ export { ScreenshareView } from "../components/ScreenshareView";
3
+ //# sourceMappingURL=screenshare-view-bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshare-view-bundle.d.ts","sourceRoot":"","sources":["../../src/ui/screenshare-view-bundle.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { interact } from "./ScreenshareOperatorSurface.interact";
2
+ import { ScreenshareView } from "../components/ScreenshareView.js";
3
+ export {
4
+ ScreenshareView,
5
+ interact
6
+ };
7
+ //# sourceMappingURL=screenshare-view-bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/screenshare-view-bundle.ts"],"sourcesContent":["// Vite view-bundle entry. Re-exports the unified spatial view component plus the\n// `interact` capability handler so the built bundle (dist/views/bundle.js)\n// exposes the named exports the view loader reads (`ScreenshareView`,\n// `interact`). One source drives GUI, XR, and TUI. Kept separate from\n// ScreenshareView.tsx so that file exports only React components and stays\n// Fast-Refresh-compatible in dev.\nexport { interact } from \"./ScreenshareOperatorSurface.interact\";\nexport { ScreenshareView } from \"../components/ScreenshareView.js\";\n"],"mappings":"AAMA,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;","names":[]}
@@ -0,0 +1,507 @@
1
+ import { client as e, selectLatestRunForApp as t, useAppSelector as n } from "@elizaos/ui";
2
+ import { Button as r, Card as i, Divider as a, Field as o, HStack as s, List as c, SpatialSurface as l, Text as u, VStack as d } from "@elizaos/ui/spatial";
3
+ import { useCallback as f, useEffect as p, useMemo as m, useRef as h, useState as g } from "react";
4
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
5
+ //#region src/ui/ScreenshareOperatorSurface.helpers.ts
6
+ function y(t) {
7
+ let n = e.getBaseUrl();
8
+ return n ? `${n}${t}` : t;
9
+ }
10
+ async function b(t, n) {
11
+ let r = e.getRestAuthToken(), i = await fetch(y(t), {
12
+ ...n,
13
+ headers: {
14
+ ...n?.body ? { "Content-Type": "application/json" } : {},
15
+ ...r ? { Authorization: `Bearer ${r}` } : {},
16
+ ...n?.headers
17
+ }
18
+ }), a = await i.json().catch(() => null);
19
+ if (!i.ok) {
20
+ let e = a && typeof a == "object" && "error" in a && typeof a.error == "string" ? a.error : `Request failed (${i.status})`;
21
+ throw Error(e);
22
+ }
23
+ return a;
24
+ }
25
+ function x(e) {
26
+ let t = new URLSearchParams({
27
+ sessionId: e.sessionId,
28
+ token: e.token
29
+ }), n = e.baseUrl?.trim().replace(/\/+$/, "") ?? "";
30
+ return n ? (t.set("remoteBase", n), `${n}/api/apps/screenshare/viewer?${t.toString()}`) : y(`/api/apps/screenshare/viewer?${t.toString()}`);
31
+ }
32
+ async function S() {
33
+ let [e, t] = await Promise.all([b("/api/apps/screenshare/capabilities"), b("/api/apps/screenshare/sessions")]);
34
+ return {
35
+ capabilities: e,
36
+ sessions: t
37
+ };
38
+ }
39
+ //#endregion
40
+ //#region src/ui/ScreenshareOperatorSurface.interact.ts
41
+ async function C(e, t) {
42
+ if (e === "terminal-screenshare-state") return {
43
+ viewType: "tui",
44
+ ...await S()
45
+ };
46
+ if (e === "terminal-screenshare-start") return {
47
+ viewType: "tui",
48
+ ...await b("/api/apps/screenshare/session", {
49
+ method: "POST",
50
+ body: JSON.stringify({ label: typeof t?.label == "string" ? t.label : "Terminal" })
51
+ })
52
+ };
53
+ if (e === "terminal-screenshare-session") {
54
+ let e = typeof t?.sessionId == "string" ? t.sessionId.trim() : "", n = typeof t?.token == "string" ? t.token.trim() : "";
55
+ if (!e) throw Error("sessionId is required");
56
+ if (!n) throw Error("token is required");
57
+ return {
58
+ viewType: "tui",
59
+ ...await b(`/api/apps/screenshare/session/${encodeURIComponent(e)}?token=${encodeURIComponent(n)}`)
60
+ };
61
+ }
62
+ if (e === "terminal-screenshare-stop") {
63
+ let e = typeof t?.sessionId == "string" ? t.sessionId.trim() : "", n = typeof t?.token == "string" ? t.token.trim() : "";
64
+ if (!e) throw Error("sessionId is required");
65
+ if (!n) throw Error("token is required");
66
+ return {
67
+ viewType: "tui",
68
+ ...await b(`/api/apps/screenshare/session/${encodeURIComponent(e)}/stop`, {
69
+ method: "POST",
70
+ body: JSON.stringify({ token: n }),
71
+ headers: { "X-Screenshare-Token": n }
72
+ })
73
+ };
74
+ }
75
+ if (e === "terminal-screenshare-input") {
76
+ let e = typeof t?.sessionId == "string" ? t.sessionId.trim() : "", n = typeof t?.token == "string" ? t.token.trim() : "";
77
+ if (!e) throw Error("sessionId is required");
78
+ if (!n) throw Error("token is required");
79
+ return {
80
+ viewType: "tui",
81
+ ...await b(`/api/apps/screenshare/session/${encodeURIComponent(e)}/input`, {
82
+ method: "POST",
83
+ body: JSON.stringify({
84
+ token: n,
85
+ type: typeof t?.type == "string" ? t.type : "keypress",
86
+ keys: typeof t?.keys == "string" ? t.keys : void 0,
87
+ text: typeof t?.text == "string" ? t.text : void 0,
88
+ x: typeof t?.x == "number" ? t.x : void 0,
89
+ y: typeof t?.y == "number" ? t.y : void 0,
90
+ button: typeof t?.button == "string" ? t.button : void 0,
91
+ deltaY: typeof t?.deltaY == "number" ? t.deltaY : void 0
92
+ }),
93
+ headers: { "X-Screenshare-Token": n }
94
+ })
95
+ };
96
+ }
97
+ if (e === "terminal-screenshare-viewer-url") {
98
+ let e = typeof t?.sessionId == "string" ? t.sessionId.trim() : "", n = typeof t?.token == "string" ? t.token.trim() : "";
99
+ if (!e) throw Error("sessionId is required");
100
+ if (!n) throw Error("token is required");
101
+ return {
102
+ viewType: "tui",
103
+ viewerUrl: x({
104
+ baseUrl: typeof t?.baseUrl == "string" ? t.baseUrl : "",
105
+ sessionId: e,
106
+ token: n
107
+ })
108
+ };
109
+ }
110
+ throw Error(`Unsupported capability "${e}"`);
111
+ }
112
+ //#endregion
113
+ //#region src/components/ScreenshareSpatialView.tsx
114
+ function w(e) {
115
+ switch (e) {
116
+ case "active": return "success";
117
+ case "stopped": return "danger";
118
+ default: return "muted";
119
+ }
120
+ }
121
+ function T(e) {
122
+ return e ? "ok" : "off";
123
+ }
124
+ function E({ snapshot: e, onAction: t }) {
125
+ let n = (e) => () => t?.(e), l = e.session, f = l?.status === "active", p = e.capabilities.filter((e) => e.available).length, m = !!(e.remote?.sessionId.trim() && e.remote?.token.trim());
126
+ return /* @__PURE__ */ v(i, {
127
+ gap: 1,
128
+ padding: 1,
129
+ children: [
130
+ /* @__PURE__ */ v(s, {
131
+ gap: 1,
132
+ align: "center",
133
+ children: [/* @__PURE__ */ _(u, {
134
+ style: "caption",
135
+ tone: f ? "success" : w(l?.status ?? "idle"),
136
+ grow: 1,
137
+ children: e.loading ? "loading" : l?.status ?? "idle"
138
+ }), /* @__PURE__ */ _(u, {
139
+ style: "caption",
140
+ tone: "muted",
141
+ children: e.platform || "desktop"
142
+ })]
143
+ }),
144
+ e.error ? /* @__PURE__ */ _(u, {
145
+ tone: "danger",
146
+ style: "caption",
147
+ children: e.error
148
+ }) : null,
149
+ /* @__PURE__ */ _(a, { label: "session" }),
150
+ l ? /* @__PURE__ */ v(d, {
151
+ gap: 0,
152
+ children: [
153
+ /* @__PURE__ */ v(s, {
154
+ gap: 1,
155
+ align: "center",
156
+ children: [
157
+ /* @__PURE__ */ _(u, {
158
+ tone: w(l.status),
159
+ children: l.status === "active" ? ">" : "."
160
+ }),
161
+ /* @__PURE__ */ _(u, {
162
+ bold: !0,
163
+ wrap: !1,
164
+ grow: 1,
165
+ children: l.label || l.id
166
+ }),
167
+ /* @__PURE__ */ _(u, {
168
+ style: "caption",
169
+ tone: "muted",
170
+ children: l.platform
171
+ })
172
+ ]
173
+ }),
174
+ /* @__PURE__ */ v(s, {
175
+ gap: 1,
176
+ children: [/* @__PURE__ */ v(u, {
177
+ style: "caption",
178
+ tone: "muted",
179
+ grow: 1,
180
+ children: ["frames ", l.frameCount]
181
+ }), /* @__PURE__ */ v(u, {
182
+ style: "caption",
183
+ tone: "muted",
184
+ grow: 1,
185
+ children: ["inputs ", l.inputCount]
186
+ })]
187
+ }),
188
+ /* @__PURE__ */ v(s, {
189
+ gap: 1,
190
+ children: [/* @__PURE__ */ v(u, {
191
+ style: "caption",
192
+ tone: "muted",
193
+ grow: 1,
194
+ children: ["last frame ", l.lastFrameAt ?? "never"]
195
+ }), /* @__PURE__ */ v(u, {
196
+ style: "caption",
197
+ tone: "muted",
198
+ grow: 1,
199
+ children: ["last input ", l.lastInputAt ?? "never"]
200
+ })]
201
+ })
202
+ ]
203
+ }) : /* @__PURE__ */ _(u, {
204
+ tone: "muted",
205
+ align: "center",
206
+ style: "caption",
207
+ children: "Idle"
208
+ }),
209
+ /* @__PURE__ */ v(s, {
210
+ gap: 1,
211
+ wrap: !0,
212
+ children: [
213
+ /* @__PURE__ */ _(r, {
214
+ grow: 1,
215
+ agent: "start",
216
+ disabled: e.busy === "start",
217
+ onPress: n(f ? "rotate" : "start"),
218
+ children: f ? "Rotate" : "Start"
219
+ }),
220
+ /* @__PURE__ */ _(r, {
221
+ variant: "outline",
222
+ tone: "default",
223
+ grow: 1,
224
+ agent: "open-viewer",
225
+ disabled: !e.host,
226
+ onPress: n("open-viewer"),
227
+ children: "Open"
228
+ }),
229
+ /* @__PURE__ */ _(r, {
230
+ variant: "outline",
231
+ tone: "default",
232
+ agent: "copy",
233
+ disabled: !e.host,
234
+ onPress: n("copy"),
235
+ children: "Copy"
236
+ }),
237
+ /* @__PURE__ */ _(r, {
238
+ variant: "ghost",
239
+ tone: "danger",
240
+ agent: "stop",
241
+ disabled: !f,
242
+ onPress: n("stop"),
243
+ children: "Stop"
244
+ })
245
+ ]
246
+ }),
247
+ /* @__PURE__ */ _(a, { label: "capabilities" }),
248
+ /* @__PURE__ */ v(u, {
249
+ style: "caption",
250
+ tone: "muted",
251
+ children: [
252
+ p,
253
+ " live / ",
254
+ e.capabilities.length
255
+ ]
256
+ }),
257
+ e.capabilities.length === 0 ? /* @__PURE__ */ _(u, {
258
+ tone: "muted",
259
+ align: "center",
260
+ style: "caption",
261
+ children: "None"
262
+ }) : /* @__PURE__ */ _(c, {
263
+ gap: 0,
264
+ children: e.capabilities.map((e) => /* @__PURE__ */ v(s, {
265
+ gap: 1,
266
+ align: "center",
267
+ agent: `cap-${e.name}`,
268
+ children: [
269
+ /* @__PURE__ */ _(u, {
270
+ tone: e.available ? "success" : "danger",
271
+ children: T(e.available)
272
+ }),
273
+ /* @__PURE__ */ _(u, {
274
+ bold: !0,
275
+ wrap: !1,
276
+ grow: 1,
277
+ children: e.name
278
+ }),
279
+ /* @__PURE__ */ _(u, {
280
+ style: "caption",
281
+ tone: "muted",
282
+ wrap: !1,
283
+ children: e.tool
284
+ })
285
+ ]
286
+ }, e.name))
287
+ }),
288
+ /* @__PURE__ */ _(a, { label: "connect" }),
289
+ /* @__PURE__ */ _(o, {
290
+ label: "Remote server URL",
291
+ value: e.remote?.baseUrl ?? "",
292
+ placeholder: "Server URL",
293
+ agent: "input-remote-base",
294
+ onChange: (e) => t?.(`remote-base:${e}`)
295
+ }),
296
+ /* @__PURE__ */ _(o, {
297
+ label: "Remote session id",
298
+ value: e.remote?.sessionId ?? "",
299
+ placeholder: "Session",
300
+ agent: "input-remote-session",
301
+ onChange: (e) => t?.(`remote-session:${e}`)
302
+ }),
303
+ /* @__PURE__ */ _(o, {
304
+ label: "Remote session token",
305
+ value: e.remote?.token ?? "",
306
+ placeholder: "Token",
307
+ kind: "password",
308
+ agent: "input-remote-token",
309
+ onChange: (e) => t?.(`remote-token:${e}`)
310
+ }),
311
+ /* @__PURE__ */ v(s, {
312
+ gap: 1,
313
+ children: [/* @__PURE__ */ _(r, {
314
+ grow: 1,
315
+ variant: m ? "solid" : "outline",
316
+ tone: m ? "primary" : "default",
317
+ agent: "connect",
318
+ disabled: !m,
319
+ onPress: n("connect"),
320
+ children: "Connect"
321
+ }), /* @__PURE__ */ _(r, {
322
+ variant: "outline",
323
+ tone: "default",
324
+ agent: "refresh",
325
+ disabled: e.loading,
326
+ onPress: n("refresh"),
327
+ children: "Refresh"
328
+ })]
329
+ })
330
+ ]
331
+ });
332
+ }
333
+ //#endregion
334
+ //#region src/components/ScreenshareView.tsx
335
+ var D = "@elizaos/plugin-screenshare";
336
+ function O(e) {
337
+ if (!e) return null;
338
+ let t = new Date(e);
339
+ return Number.isNaN(t.getTime()) ? null : t.toLocaleTimeString();
340
+ }
341
+ function k(e) {
342
+ if (!e) return null;
343
+ try {
344
+ let t = new URL(e, window.location.origin), n = t.searchParams.get("sessionId")?.trim(), r = t.searchParams.get("token")?.trim();
345
+ return n && r ? {
346
+ sessionId: n,
347
+ token: r
348
+ } : null;
349
+ } catch {
350
+ return null;
351
+ }
352
+ }
353
+ function A(e) {
354
+ return e ? Object.entries(e.capabilities).map(([e, t]) => ({
355
+ name: e,
356
+ available: t.available,
357
+ tool: t.tool
358
+ })) : [];
359
+ }
360
+ function j() {
361
+ let r = n((e) => e.appRuns), { run: i } = m(() => t(D, r), [r]), a = m(() => k(i?.viewer?.url), [i?.viewer?.url]), [o, s] = g(null), [c, u] = g(null), [d, v] = g(a?.token ?? ""), [y, S] = g(""), [C, w] = g(""), [T, j] = g(""), [M, N] = g(null), [P, F] = g(!1), [I, L] = g(null), R = f(async () => {
362
+ F(!0), L(null);
363
+ try {
364
+ s(await b("/api/apps/screenshare/capabilities"));
365
+ } catch (e) {
366
+ L(e instanceof Error ? e.message : "Failed to load capabilities.");
367
+ } finally {
368
+ F(!1);
369
+ }
370
+ }, []), z = h(!1);
371
+ p(() => {
372
+ z.current || (z.current = !0, R());
373
+ let e = setInterval(() => {
374
+ R();
375
+ }, 2e4);
376
+ return () => clearInterval(e);
377
+ }, [R]), p(() => {
378
+ a && (v(a.token), b(`/api/apps/screenshare/session/${encodeURIComponent(a.sessionId)}?token=${encodeURIComponent(a.token)}`).then((e) => u(e.session)).catch((e) => L(e instanceof Error ? e.message : "Failed to load screen share session.")));
379
+ }, [a]);
380
+ let B = f(async () => {
381
+ N("start"), L(null);
382
+ try {
383
+ let e = await b("/api/apps/screenshare/session", {
384
+ method: "POST",
385
+ body: JSON.stringify({ label: "This machine" })
386
+ });
387
+ u(e.session), v(e.token);
388
+ } catch (e) {
389
+ L(e instanceof Error ? e.message : "Failed to start session.");
390
+ } finally {
391
+ N(null);
392
+ }
393
+ }, []), V = f(async () => {
394
+ if (!(!c || !d)) {
395
+ N("stop"), L(null);
396
+ try {
397
+ u((await b(`/api/apps/screenshare/session/${encodeURIComponent(c.id)}/stop`, {
398
+ method: "POST",
399
+ body: JSON.stringify({ token: d }),
400
+ headers: { "X-Screenshare-Token": d }
401
+ })).session);
402
+ } catch (e) {
403
+ L(e instanceof Error ? e.message : "Failed to stop session.");
404
+ } finally {
405
+ N(null);
406
+ }
407
+ }
408
+ }, [c, d]), H = f(async () => {
409
+ if (!c || !d) return;
410
+ let t = x({
411
+ sessionId: c.id,
412
+ token: d
413
+ });
414
+ try {
415
+ await navigator.clipboard.writeText(JSON.stringify({
416
+ serverUrl: e.getBaseUrl() || window.location.origin,
417
+ sessionId: c.id,
418
+ token: d,
419
+ viewerUrl: t
420
+ }, null, 2));
421
+ } catch (e) {
422
+ L(e instanceof Error ? e.message : "Clipboard write failed.");
423
+ }
424
+ }, [c, d]), U = c && d ? x({
425
+ sessionId: c.id,
426
+ token: d
427
+ }) : null, W = C.trim() && T.trim() ? x({
428
+ baseUrl: y,
429
+ sessionId: C.trim(),
430
+ token: T.trim()
431
+ }) : null, G = f((e) => {
432
+ if (e.startsWith("remote-base:")) {
433
+ S(e.slice(12));
434
+ return;
435
+ }
436
+ if (e.startsWith("remote-session:")) {
437
+ w(e.slice(15));
438
+ return;
439
+ }
440
+ if (e.startsWith("remote-token:")) {
441
+ j(e.slice(13));
442
+ return;
443
+ }
444
+ switch (e) {
445
+ case "start":
446
+ case "rotate":
447
+ B();
448
+ return;
449
+ case "stop":
450
+ V();
451
+ return;
452
+ case "copy":
453
+ H();
454
+ return;
455
+ case "open-viewer":
456
+ U && window.open(U, "_blank", "noopener,noreferrer");
457
+ return;
458
+ case "connect":
459
+ W && window.open(W, "_blank", "noopener,noreferrer");
460
+ return;
461
+ case "refresh":
462
+ R();
463
+ return;
464
+ }
465
+ }, [
466
+ H,
467
+ U,
468
+ R,
469
+ W,
470
+ B,
471
+ V
472
+ ]);
473
+ return /* @__PURE__ */ _(l, { children: /* @__PURE__ */ _(E, {
474
+ snapshot: {
475
+ platform: o?.platform ?? c?.platform ?? "desktop",
476
+ session: c ? {
477
+ id: c.id,
478
+ label: c.label,
479
+ status: c.status,
480
+ platform: c.platform,
481
+ frameCount: c.frameCount,
482
+ inputCount: c.inputCount,
483
+ lastFrameAt: O(c.lastFrameAt),
484
+ lastInputAt: O(c.lastInputAt)
485
+ } : null,
486
+ capabilities: A(o),
487
+ host: U ? {
488
+ token: d,
489
+ sessionId: c?.id ?? "",
490
+ baseUrl: e.getBaseUrl() || ""
491
+ } : null,
492
+ remote: y || C || T ? {
493
+ token: T,
494
+ sessionId: C,
495
+ baseUrl: y
496
+ } : null,
497
+ loading: P,
498
+ busy: M,
499
+ error: I
500
+ },
501
+ onAction: G
502
+ }) });
503
+ }
504
+ //#endregion
505
+ export { j as ScreenshareView, C as interact };
506
+
507
+ //# sourceMappingURL=bundle.js.map