feat(v2): add frontend remote machine integration
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.
This commit is contained in:
parent
0b39133d66
commit
5503340e87
7 changed files with 481 additions and 5 deletions
97
v2/src/lib/stores/machines.svelte.ts
Normal file
97
v2/src/lib/stores/machines.svelte.ts
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
// 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}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue