/** * The persisted Cloud sign-in (`/cloud/config.json`): the single * place that locates, reads (with repair) and writes it. The backend and the * `crewly cloud login` CLI both go through here. * * Incident (2026-10-11): two overlapping `writeFile` calls (token refresh + * relay-token refresh) interleaved, the shorter payload landed last and the * file ended up as a complete JSON object followed by the tail of the longer * one. `JSON.parse` failed, Crewly acted signed-out for >24 h and nobody was * told. Writes are now atomic and serialized; reads repair that exact damage * and report anything else instead of silently reading as "not signed in". * * @module services/cloud/cloud-config-file */ import { type FileIOLogger } from '../../utils/file-io.utils.js'; /** Credentials are owner-only. */ export declare const CLOUD_CONFIG_FILE_MODE = 384; /** * Persisted cloud config stored at ~/.crewly/cloud/config.json. * Enables auto-reconnect on backend restart. */ export interface PersistedCloudConfig { cloudUrl: string; token: string; tier: string; connectedAt: string; /** Refresh token for auto-renewing expired access tokens */ refreshToken?: string; /** * Relay-signed access JWT (distinct from the access `token`). Persisted so * the BrowserProxy can re-register on backend restart without waiting for a * fresh validate round-trip. Never the Google/Supabase token — see the * RELAY-TOKEN-TYPE invariant in the long-term browser-relay fix design. */ relayToken?: string; } /** What {@link readCloudConfigFile} found. */ export type CloudConfigRead = { status: 'missing'; } | { status: 'ok'; config: PersistedCloudConfig; repaired: boolean; } | { status: 'damaged'; reason: string; quarantinedTo: string | null; }; /** * Path to the persisted cloud config. Resolved through CREWLY_HOME per call so * tests (which isolate CREWLY_HOME) can never touch the real login. * * @returns Absolute file path */ export declare function getCloudConfigPath(): string; /** * Shape check: a usable sign-in has a URL, an access token and a tier. * * @param data - Parsed JSON * @returns Error text, or null when valid */ export declare function validateCloudConfig(data: unknown): string | null; /** * Read the cloud config. A file with stale trailing bytes after a complete * object is repaired in place (atomic, WARN logged); an unusable file is * backed up to `config.json.corrupt-` and reported as `damaged`. * * @param logger - Optional logger * @returns missing / ok / damaged */ export declare function readCloudConfigFile(logger?: FileIOLogger): CloudConfigRead; /** * Write the cloud config atomically (mode 600, serialized in this process). * * @param config - Config to persist */ export declare function writeCloudConfigFile(config: PersistedCloudConfig): Promise; /** * Synchronous {@link writeCloudConfigFile} for the CLI. * * @param config - Config (or a superset of it) to persist */ export declare function writeCloudConfigFileSync(config: PersistedCloudConfig): void; //# sourceMappingURL=cloud-config-file.d.ts.map