/** * Harness<->CLI version contract (ce-5qp). The management image ships a * baked-in `celilo` CLI; a published harness run against a stale image * (e.g. an old npm consumer's `cele2e build-infra`) used to hang ~90s in * `system init` and surface only "canceled". Instead we check the baked CLI * version up front and fail fast (<10s) with an actionable message. * * Bump MIN_CLI_VERSION whenever the harness starts relying on a CLI * feature/flag that older CLIs lack. It's the MINIMUM the harness needs, * not an exact pin. */ export const MIN_CLI_VERSION = '0.9.0'; /** * Pure core of the contract: given the raw `celilo --version` stdout, decide * whether it satisfies `minVersion`. Returns an actionable error string when * it doesn't, or `null` when OK. No I/O, so it's unit-testable without a * running management container. */ export function checkCliVersion( versionStdout: string, minVersion = MIN_CLI_VERSION, ): string | null { // Output is `celilo ` (apps/celilo displayVersion). Grab the token. const version = versionStdout.match(/celilo\s+(\S+)/)?.[1]; if (!version) { return ( `Could not parse celilo version from "${versionStdout.trim()}" ` + `(harness requires >=${minVersion}). Is the management image's celilo CLI intact?` ); } if (Bun.semver.order(version, minVersion) < 0) { return `Management image has celilo ${version}, harness requires >=${minVersion}. Rebuild the management image against a newer @celilo/cli (e.g. \`cele2e build-infra\`, or \`--published\` after publishing).`; } return null; }