import type { PowerLineConnection, ProvisionEvent } from "./adapter.js"; import type { AdapterDependencies, ExecFunction } from "./adapter-dependencies.js"; import type { BootstrapOptions, StartRemotePowerLineOptions } from "./bootstrap.js"; import type { RemoteExecutor } from "./remote-executor.js"; import type { ProcessTunnel } from "./tunnel.js"; import type { TunnelState } from "./tunnel-registry.js"; import type { BaseEnvironmentConfig } from "./adapter.js"; import { BaseAdapter } from "./base-adapter.js"; import { TunnelRegistry } from "./tunnel-registry.js"; /** Configuration fields shared by all remote-tunnel-based adapters. */ export interface RemoteTunnelConfig extends BaseEnvironmentConfig { /** Override the local tunnel port (otherwise a free port is chosen). */ localPort?: number; /** Additional environment variables forwarded to the remote PowerLine. */ env?: Record; } /** Display metadata returned by {@link RemoteTunnelAdapter.resolveConfig}. */ export interface RemoteTunnelMeta { /** Human-readable target name for progress messages (e.g. "my-host", "codespace 'abc'"). */ displayTarget: string; } /** * Abstract base for adapters that connect to a remote host via a process-backed * tunnel (SSH, gh codespace ports forward, etc.). * * Implements the full provision/reconnect/connect/disconnect/stop/destroy/healthCheck * lifecycle once. Subclasses provide four factory methods that encapsulate the * transport-specific differences (executor commands, tunnel arguments). * * @typeParam TConfig - Adapter-specific configuration extending {@link RemoteTunnelConfig}. */ export declare abstract class RemoteTunnelAdapter extends BaseAdapter { protected readonly execFn: ExecFunction; protected readonly sleepFn: (ms: number) => Promise; protected readonly isGitHubProviderEnabled: () => boolean; protected readonly resolveGitHubToken: (accountId?: string) => string | undefined; protected readonly tunnelRegistry: TunnelRegistry; constructor(deps?: AdapterDependencies); /** * Validate raw config and return typed config + display metadata. * Throw if required fields are missing. */ protected abstract resolveConfig(config: Record): { config: TConfig; meta: RemoteTunnelMeta; }; /** Create a {@link RemoteExecutor} for running commands on the remote host. */ protected abstract createExecutor(config: TConfig): RemoteExecutor; /** Create a forward tunnel (local port → remote PowerLine port). */ protected abstract createForwardTunnel(localPort: number, config: TConfig): ProcessTunnel; /** Create a reverse tunnel (remote port → local MCP port). */ protected abstract createReverseTunnel(localPort: number, remotePort: number, config: TConfig): ProcessTunnel; /** * Post-connectivity hook called before bootstrap. * Override to detect the remote working directory (e.g. `/workspaces/*` on codespaces). * Default returns no working directory. */ protected preBootstrap(_executor: RemoteExecutor, _config: TConfig): Promise<{ workingDirectory?: string; }>; /** * Additional options merged into {@link startRemotePowerLine} during reconnect. * Override to supply adapter-specific options (e.g. `{ autoDetectWorkspace: true }`). */ protected reconnectBootstrapOptions(_config: TConfig): Partial; /** Run the PowerLine bootstrap sequence on the remote host. */ protected runBootstrap(executor: RemoteExecutor, powerlineToken: string, options: BootstrapOptions): AsyncGenerator; /** Probe and optionally restart the remote PowerLine. */ protected runStartPowerLine(executor: RemoteExecutor, powerlineToken: string, options: StartRemotePowerLineOptions): Promise<{ alreadyRunning: boolean; }>; /** Open a tunnel with automatic free-port discovery. */ protected openWithFreePort(action: (port: number) => Promise): Promise; /** Connect to the PowerLine via the tunnel. */ protected connectToTunnel(environmentId: string, localPort: number, powerlineToken: string): Promise; /** Close and unregister the tunnel(s) for an environment. */ protected closeTunnelForEnvironment(environmentId: string): Promise; /** Register an active tunnel pair for an environment. */ protected registerTunnelForEnvironment(environmentId: string, state: TunnelState): void; /** Get the tunnel state for an environment. */ protected getTunnelForEnvironment(environmentId: string): TunnelState | undefined; /** Stop the remote PowerLine and close the tunnel. */ protected runRemoteStop(environmentId: string, executor: RemoteExecutor): Promise; /** Destroy remote PowerLine artifacts and close the tunnel. */ protected runRemoteDestroy(environmentId: string, executor: RemoteExecutor): Promise; /** Ping the PowerLine to check liveness. */ protected runHealthCheck(connection: PowerLineConnection): Promise; /** Provision the remote host: test connectivity, bootstrap PowerLine, open tunnels. */ protected doProvision(environmentId: string, config: Record, powerlineToken: string): AsyncGenerator; /** * Attempt fast reconnect: probe PowerLine, restart if needed, re-open tunnels. * * Any failure throws and falls through to the caller, which should trigger * a full provision via {@link reconnectOrProvision}. */ reconnect(environmentId: string, config: Record, powerlineToken: string): AsyncGenerator; private doReconnect; /** Connect to the PowerLine through the tunnel. */ protected doConnect(environmentId: string, _config: Record, powerlineToken: string): Promise; /** Close the tunnel without stopping the remote PowerLine. */ protected doDisconnect(environmentId: string): Promise; /** Stop the remote PowerLine process and close the tunnel. */ protected doStop(environmentId: string, config: Record): Promise; /** Stop the remote PowerLine, remove artifacts, and close the tunnel. */ protected doDestroy(environmentId: string, config: Record): Promise; /** Check that the tunnel is alive and the PowerLine responds to a ping. */ healthCheck(connection: PowerLineConnection): Promise; } //# sourceMappingURL=remote-tunnel-adapter.d.ts.map