remote-bridge.ts adapter for machine management IPC. machines.svelte.ts store for remote machine state. Layout store extended with remoteMachineId on Pane interface. agent-bridge.ts and pty-bridge.ts route to remote commands when remoteMachineId is set. SettingsDialog gains Remote Machines section. Sidebar auto-groups remote panes by machine label.
97 lines
2.6 KiB
TypeScript
97 lines
2.6 KiB
TypeScript
// Remote machines store — tracks connection state for multi-machine support
|
|
|
|
import {
|
|
listRemoteMachines,
|
|
addRemoteMachine,
|
|
removeRemoteMachine,
|
|
connectRemoteMachine,
|
|
disconnectRemoteMachine,
|
|
onRemoteMachineReady,
|
|
onRemoteMachineDisconnected,
|
|
onRemoteError,
|
|
type RemoteMachineConfig,
|
|
type RemoteMachineInfo,
|
|
} from '../adapters/remote-bridge';
|
|
import { notify } from './notifications.svelte';
|
|
|
|
export interface Machine extends RemoteMachineInfo {}
|
|
|
|
let machines = $state<Machine[]>([]);
|
|
|
|
export function getMachines(): Machine[] {
|
|
return machines;
|
|
}
|
|
|
|
export function getMachine(id: string): Machine | undefined {
|
|
return machines.find(m => m.id === id);
|
|
}
|
|
|
|
export async function loadMachines(): Promise<void> {
|
|
try {
|
|
machines = await listRemoteMachines();
|
|
} catch (e) {
|
|
console.warn('Failed to load remote machines:', e);
|
|
}
|
|
}
|
|
|
|
export async function addMachine(config: RemoteMachineConfig): Promise<string> {
|
|
const id = await addRemoteMachine(config);
|
|
machines.push({
|
|
id,
|
|
label: config.label,
|
|
url: config.url,
|
|
status: 'disconnected',
|
|
auto_connect: config.auto_connect,
|
|
});
|
|
return id;
|
|
}
|
|
|
|
export async function removeMachine(id: string): Promise<void> {
|
|
await removeRemoteMachine(id);
|
|
machines = machines.filter(m => m.id !== id);
|
|
}
|
|
|
|
export async function connectMachine(id: string): Promise<void> {
|
|
const machine = machines.find(m => m.id === id);
|
|
if (machine) machine.status = 'connecting';
|
|
try {
|
|
await connectRemoteMachine(id);
|
|
if (machine) machine.status = 'connected';
|
|
} catch (e) {
|
|
if (machine) machine.status = 'error';
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
export async function disconnectMachine(id: string): Promise<void> {
|
|
await disconnectRemoteMachine(id);
|
|
const machine = machines.find(m => m.id === id);
|
|
if (machine) machine.status = 'disconnected';
|
|
}
|
|
|
|
// Initialize event listeners for machine status updates
|
|
export async function initMachineListeners(): Promise<void> {
|
|
await onRemoteMachineReady((msg) => {
|
|
const machine = machines.find(m => m.id === msg.machineId);
|
|
if (machine) {
|
|
machine.status = 'connected';
|
|
notify('success', `Connected to ${machine.label}`);
|
|
}
|
|
});
|
|
|
|
await onRemoteMachineDisconnected((msg) => {
|
|
const machine = machines.find(m => m.id === msg.machineId);
|
|
if (machine) {
|
|
machine.status = 'disconnected';
|
|
notify('warning', `Disconnected from ${machine.label}`);
|
|
}
|
|
});
|
|
|
|
await onRemoteError((msg) => {
|
|
const machine = machines.find(m => m.id === msg.machineId);
|
|
if (machine) {
|
|
machine.status = 'error';
|
|
notify('error', `Error from ${machine.label}: ${msg.error}`);
|
|
}
|
|
});
|
|
}
|