feat(electrobun): multi-machine relay + OTEL telemetry

Multi-machine relay:
- relay-client.ts: WebSocket client for agor-relay with token auth,
  exponential backoff (1s-30s), TCP probe, heartbeat (15s ping)
- machines-store.svelte.ts: remote machine state tracking
- RemoteMachinesSettings.svelte: machine list, add/connect/disconnect UI
- 7 RPC types (remote.connect/disconnect/list/send/status + events)

Telemetry:
- telemetry.ts: OTEL spans + OTLP/HTTP export to Tempo,
  controlled by AGOR_OTLP_ENDPOINT env var
- telemetry-bridge.ts: tel.info/warn/error frontend convenience API
- telemetry.log RPC for frontend→Bun tracing
This commit is contained in:
Hibryda 2026-03-22 01:46:03 +01:00
parent ec30c69c3e
commit 88206205fe
11 changed files with 1458 additions and 15 deletions

View file

@ -1,12 +1,13 @@
<script lang="ts">
import AppearanceSettings from './settings/AppearanceSettings.svelte';
import AgentSettings from './settings/AgentSettings.svelte';
import SecuritySettings from './settings/SecuritySettings.svelte';
import ProjectSettings from './settings/ProjectSettings.svelte';
import OrchestrationSettings from './settings/OrchestrationSettings.svelte';
import AdvancedSettings from './settings/AdvancedSettings.svelte';
import MarketplaceTab from './settings/MarketplaceTab.svelte';
import KeyboardSettings from './settings/KeyboardSettings.svelte';
import AppearanceSettings from './settings/AppearanceSettings.svelte';
import AgentSettings from './settings/AgentSettings.svelte';
import SecuritySettings from './settings/SecuritySettings.svelte';
import ProjectSettings from './settings/ProjectSettings.svelte';
import OrchestrationSettings from './settings/OrchestrationSettings.svelte';
import AdvancedSettings from './settings/AdvancedSettings.svelte';
import MarketplaceTab from './settings/MarketplaceTab.svelte';
import KeyboardSettings from './settings/KeyboardSettings.svelte';
import RemoteMachinesSettings from './settings/RemoteMachinesSettings.svelte';
interface Props {
open: boolean;
@ -15,7 +16,7 @@
let { open, onClose }: Props = $props();
type CategoryId = 'appearance' | 'agents' | 'security' | 'projects' | 'orchestration' | 'advanced' | 'marketplace' | 'keyboard';
type CategoryId = 'appearance' | 'agents' | 'security' | 'projects' | 'orchestration' | 'machines' | 'advanced' | 'marketplace' | 'keyboard';
interface Category {
id: CategoryId;
@ -29,6 +30,7 @@
{ id: 'security', label: 'Security', icon: '🔒' },
{ id: 'projects', label: 'Projects', icon: '📁' },
{ id: 'orchestration', label: 'Orchestration', icon: '⚙' },
{ id: 'machines', label: 'Machines', icon: '🖥' },
{ id: 'keyboard', label: 'Keyboard', icon: '⌨' },
{ id: 'advanced', label: 'Advanced', icon: '🔧' },
{ id: 'marketplace', label: 'Marketplace', icon: '🛒' },
@ -94,6 +96,8 @@
<ProjectSettings />
{:else if activeCategory === 'orchestration'}
<OrchestrationSettings />
{:else if activeCategory === 'machines'}
<RemoteMachinesSettings />
{:else if activeCategory === 'advanced'}
<AdvancedSettings />
{:else if activeCategory === 'keyboard'}