import { readFileSync } from "node:fs"; function assertCondition(condition: unknown, message: string, detail: unknown = {}): void { if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`); } const rustBridge = readFileSync("src/components/backend-core/src/ssh_bridge.rs", "utf8"); const rustData = readFileSync("src/components/backend-core/src/ssh_data_channel.rs", "utf8"); const rustMain = readFileSync("src/components/backend-core/src/main.rs", "utf8"); const rustState = readFileSync("src/components/backend-core/src/state.rs", "utf8"); const rustProviderRegistry = readFileSync("src/components/backend-core/src/provider_registry.rs", "utf8"); const provider = readFileSync("src/components/provider-gateway/src/index.ts", "utf8"); const providerRegistryTs = readFileSync("src/components/backend-core/src/provider-registry.ts", "utf8"); const providerPackage = JSON.parse(readFileSync("src/components/provider-gateway/package.json", "utf8")) as { version?: unknown }; const shared = readFileSync("src/components/shared/src/index.ts", "utf8"); const compose = readFileSync("docker-compose.yml", "utf8"); const config = readFileSync("config.json", "utf8"); const backendCoreDockerfile = readFileSync("src/components/backend-core/Dockerfile", "utf8"); assertCondition(rustBridge.includes('"host.ssh.tcp-pool"'), "backend-core ssh bridge must require host.ssh.tcp-pool"); assertCondition(rustBridge.includes("provider-gateway-upgrade-required"), "old provider must fail with upgrade-required classification"); assertCondition(rustBridge.includes("provider-data-pool-exhausted"), "tcp pool exhaustion must be visible"); assertCondition(!rustBridge.includes('"host_ssh_input"'), "ssh input must not fall back to provider control websocket"); assertCondition(!rustBridge.includes('"host_ssh_eof"'), "ssh eof must not fall back to provider control websocket"); assertCondition(!rustBridge.includes('"host_ssh_close"'), "ssh close must not fall back to provider control websocket"); assertCondition(rustBridge.includes('json!({ "type": "input"') && rustBridge.includes('json!({ "type": "eof"'), "ssh bridge must send stdin/eof over data frames"); assertCondition(!rustProviderRegistry.includes('"host_ssh_opened"') && !rustProviderRegistry.includes('"host_ssh_data"') && !rustProviderRegistry.includes('"host_ssh_exit"'), "rust provider registry must not accept old websocket ssh data messages"); assertCondition(rustData.includes("TcpListener") && rustData.includes("read_data_frame") && rustData.includes("write_data_frame"), "backend-core must expose raw TCP data frame listener"); assertCondition(rustData.includes("SSH_DATA_PROTOCOL") && rustData.includes("unidesk-host-ssh-tcp-pool-v1"), "tcp data protocol must be explicit"); assertCondition(rustData.includes("base64::engine::general_purpose::STANDARD.encode(payload)"), "only client-facing websocket payload should remain base64 encoded"); assertCondition(rustMain.includes("providerDataTcpUrl") && rustMain.includes("spawn_ssh_data_listener"), "backend-core startup must expose provider data listener visibility"); assertCondition(rustState.includes("active_ssh_data_channels") && rustState.includes("data_channel_id"), "backend state must track data channels separately from provider control socket"); assertCondition(provider.includes("createConnection") && provider.includes("sshDataChannels"), "provider-gateway must use direct TCP sockets for ssh data pool"); assertCondition(provider.includes("PROVIDER_DATA_POOL_SIZE") && provider.includes("providerGatewaySshDataPoolReady"), "provider-gateway must expose pool config and heartbeat labels"); assertCondition(provider.includes('capabilities.push("host.ssh", "host.ssh.tcp-pool")'), "provider-gateway must declare tcp-pool capability only with host ssh"); assertCondition(provider.includes("acquireSshDataChannel") && provider.includes("releaseSshDataChannel"), "provider-gateway must claim/release one data channel per ssh session"); assertCondition(provider.includes("writeSshDataFrame(dataChannel") && provider.includes("sendSshDataSessionFrame"), "provider-gateway ssh output must use tcp data frames"); assertCondition(!provider.includes('parsed.type === "host_ssh_input"') && !provider.includes('parsed.type === "host_ssh_close"'), "provider-gateway must not retain old websocket ssh input handlers"); assertCondition(providerPackage.version === "0.2.28", "provider-gateway behavior change must bump package version", providerPackage); assertCondition(shared.includes('transport: "tcp-pool"') && shared.includes("dataChannelId: string"), "shared host_ssh_open contract must require tcp-pool fields"); assertCondition(!shared.includes("CoreHostSshInputMessage") && !shared.includes("ProviderHostSshDataMessage"), "shared protocol must remove old websocket ssh data contracts"); assertCondition(!providerRegistryTs.includes("host_ssh_data") && !providerRegistryTs.includes("host_ssh_exit"), "typescript backend registry must not forward old websocket ssh data messages"); assertCondition(compose.includes("UNIDESK_PROVIDER_DATA_PORT") && compose.includes("PROVIDER_DATA_POOL_SIZE"), "compose must wire provider data port and pool size"); assertCondition(config.includes('"providerData"') && config.includes('"port": 18084') && config.includes('"containerPort": 8082'), "config.json must declare providerData port pair"); assertCondition(backendCoreDockerfile.includes("ARG CARGO_BUILD_JOBS=1") && backendCoreDockerfile.includes('cargo build --release --jobs "${CARGO_BUILD_JOBS}"'), "backend-core main-server online build must keep cargo concurrency constrained"); assertCondition(compose.includes("UNIDESK_BACKEND_CORE_CARGO_BUILD_JOBS") && compose.includes("CARGO_BUILD_JOBS"), "compose must pass backend-core cargo build concurrency explicitly"); console.log(JSON.stringify({ ok: true, test: "ssh-data-tcp-pool-contract" }));