import { buildAgentSendCommand, buildTmuxListPanesCommand, getRosterAgent, loadFleetRoster, parseTmuxListPanes, resolveFleetPaths, RUNTIME_ACCEPTABLE_COMMANDS, socketArgs, type CommandResult, type CommandRunner, type FleetRoster, } from '../commands/fleet.js'; export type FleetRuntimeTransportErrorCode = | 'forbidden' | 'invalid_request' | 'not_found' | 'unavailable'; /** A roster-bound, verified tmux target. It never accepts a caller-selected socket. */ export interface FleetRuntimeTarget { id: string; runtimeId: string; socketName: string; } /** Narrow transport boundary consumed by the runtime provider. */ export interface FleetRuntimeTransport { verifySession(sessionId: string): Promise; listSessions(): Promise; sendMessage(sessionId: string, message: string, sourceLabel: string): Promise; terminate(sessionId: string): Promise; } export interface FleetTmuxRuntimeTransportOptions { mosaicHome: string; rosterPath?: string; rosterLoader?: () => Promise; runner: CommandRunner; } /** A typed, fail-closed error for roster, target, identity, and tmux failures. */ export class FleetRuntimeTransportError extends Error { constructor( readonly code: FleetRuntimeTransportErrorCode, message: string, ) { super(message); this.name = FleetRuntimeTransportError.name; } } /** * Roster-bound transport for the local fleet tmux server. Every side-effecting * operation verifies an exact roster name, the roster socket, and the runtime * command in the exact pane before it invokes the maintained sender or tmux. */ export class FleetTmuxRuntimeTransport implements FleetRuntimeTransport { private readonly rosterLoader: () => Promise; constructor(private readonly options: FleetTmuxRuntimeTransportOptions) { this.rosterLoader = options.rosterLoader ?? (() => loadFleetRoster(options.rosterPath ?? resolveFleetPaths(options.mosaicHome).rosterPath)); } async verifySession(sessionId: string): Promise { const roster = await this.loadRoster(); return this.verifyRosterSession(roster, sessionId); } async listSessions(): Promise { const roster = await this.loadRoster(); const targets = await Promise.all( roster.agents.map(async (agent): Promise => { try { return await this.verifyRosterSession(roster, agent.name); } catch (error: unknown) { if (error instanceof FleetRuntimeTransportError && error.code === 'unavailable') { return undefined; } throw error; } }), ); return targets.filter((target): target is FleetRuntimeTarget => target !== undefined); } async sendMessage(sessionId: string, message: string, sourceLabel: string): Promise { if (message.length === 0) { throw new FleetRuntimeTransportError('invalid_request', 'Fleet message content is required'); } if (sourceLabel.length === 0) { throw new FleetRuntimeTransportError( 'invalid_request', 'Fleet message source label is required', ); } const target = await this.verifySession(sessionId); const command = buildAgentSendCommand( resolveFleetPaths(this.options.mosaicHome), target.id, message, target.socketName, sourceLabel, ); await this.runChecked(command, 'Fleet message delivery failed'); } async terminate(sessionId: string): Promise { const target = await this.verifySession(sessionId); await this.runChecked( ['tmux', ...socketArgs(target.socketName), 'kill-session', '-t', `=${target.id}`], 'Fleet session termination failed', ); } private async loadRoster(): Promise { try { return await this.rosterLoader(); } catch (error: unknown) { const message = error instanceof Error ? error.message : 'Fleet roster is unavailable'; throw new FleetRuntimeTransportError( 'unavailable', `Fleet roster is unavailable: ${message}`, ); } } private async verifyRosterSession( roster: FleetRoster, sessionId: string, ): Promise { const agent = this.exactRosterAgent(roster, sessionId); const socketName = roster.tmux.socketName; const result = await this.run(buildTmuxListPanesCommand(agent.name, socketName)); if (result.exitCode !== 0) { throw new FleetRuntimeTransportError( 'unavailable', `Fleet session is unavailable: ${agent.name}`, ); } const pane = parseTmuxListPanes(result.stdout); if (pane.dead || pane.command === null) { throw new FleetRuntimeTransportError( 'unavailable', `Fleet session is unavailable: ${agent.name}`, ); } if (!hasExactRuntimeIdentity(agent.runtime, pane.command)) { throw new FleetRuntimeTransportError( 'forbidden', `Fleet runtime identity mismatch: ${agent.name}`, ); } return { id: agent.name, runtimeId: agent.runtime, socketName }; } private exactRosterAgent(roster: FleetRoster, sessionId: string): FleetRoster['agents'][number] { try { const agent = getRosterAgent(roster, sessionId); if (agent.name !== sessionId) { throw new FleetRuntimeTransportError('not_found', 'Fleet session target must be exact'); } return agent; } catch (error: unknown) { if (error instanceof FleetRuntimeTransportError) { throw error; } throw new FleetRuntimeTransportError('not_found', 'Fleet session target is not roster-bound'); } } private async run(command: string[]): Promise { const [executable, ...args] = command; if (executable === undefined) { throw new FleetRuntimeTransportError('invalid_request', 'Fleet command is required'); } try { return await this.options.runner(executable, args); } catch (error: unknown) { const message = error instanceof Error ? error.message : 'Fleet command failed'; throw new FleetRuntimeTransportError('unavailable', message); } } private async runChecked(command: string[], failureMessage: string): Promise { const result = await this.run(command); if (result.exitCode !== 0) { throw new FleetRuntimeTransportError('unavailable', failureMessage); } } } function hasExactRuntimeIdentity(runtimeId: string, paneCommand: string): boolean { const expectedCommands = RUNTIME_ACCEPTABLE_COMMANDS[runtimeId]; return expectedCommands !== undefined && expectedCommands.includes(paneCommand); }