/** Discriminator for {@link ResourceRemoteSyncFailure}; library callers can ignore the tag and read `.message` / `.ok`. */ export type ResourceRemoteSyncFailureReason = "solution_not_found" | "not_a_solution" | "auth_failed" | "resource_not_found" | "no_remote_reference" | "comparison_unavailable" | "sync_failed" | "save_failed"; export interface ResourceRemoteSyncOptions { /** Write the cloud definition over the local one. When `false` (default) nothing is written and the result only reports the drift. */ force?: boolean; /** Minimum minutes before token expiration to trigger a refresh. Default `10` (matches the CLI's `--login-validity`). */ loginValidity?: number; /** Pin auth to this exact `.uipath/.auth` path. */ envFilePath?: string; } export interface ResourceRemoteSyncSuccess { ok: true; /** `true` when the cloud definition was written to disk; `false` for a drift-only (no `--force`) run. */ applied: boolean; key: string; /** Spec property names that differ between the local and the cloud definition, sorted. Empty when the two already agree. */ changed: string[]; /** Properties that still differ from the cloud after a write, because the SDK declined to set them (reference, read-only or unknown to the kind metadata). Empty on a clean sync. */ skipped: string[]; /** The resulting local spec — post-write when `applied`, unchanged otherwise. */ spec: Record; } export interface ResourceRemoteSyncFailure { ok: false; reason: ResourceRemoteSyncFailureReason; /** Human-readable summary suitable for top-level surfacing. */ message: string; } export type ResourceRemoteSyncResult = ResourceRemoteSyncSuccess | ResourceRemoteSyncFailure; /** * Programmatic core of `uip solution resources edit --source remote`: replaces a * solution resource's spec with the current cloud definition it was imported from. * * This is the one path that overwrites an already-imported resource. `refresh` is * deliberately import-only (see `sync-resources-from-bindings`), so a field added * to a cloud entity after the initial import never reaches the solution without * this command. * * Mechanism: read the cloud side with `getResourceConfigurationsComparisonAsync` * (which returns the solution config and the FPS export side by side and writes * nothing), then hand that spec to `updateConfigurationAsync` — the same writer * `resources edit --patch` uses. It mutates the existing resource in place, so * the file keeps its path and the resource keeps its key and name. * * **Two richer-looking SDK calls were tried first and both are wrong here.** * * `syncConfigurationFromReferenceAsync` looks the resource's cloud source up via * `getDebugOverwrites`, which calls the *server* rather than reading the local * `debug_overwrites.json`. For a solution never uploaded to Studio Web the server * has nothing, so it returns the resource untouched and reports success — every * `--force` was a silent no-op. Confirmed live: `getDebugOverwrites size: 0` * while the file on disk held the row. * * `addOrUpdateResourceToSolutionAsync` (and the command behind it) re-imports the * FPS export, which carries the *server* casing of `kind` — `Queue`, not `queue`. * The re-add therefore writes a second file at `resources/.../Queue/.json` * beside the original `queue/.json`. On a case-sensitive filesystem those * are two files for one resource key: the load throws "Node already added to the * graph", and once `normalizeResourceFileCasing` folds them it keeps the one * already at the target path — the stale one — silently discarding the write. * Reproduced on a case-sensitive volume; it is why only the Linux e2e leg failed. * * What survives from that: never trust a write to have happened. The spec is read * back and diffed, and anything the writer declined to set is reported in * `skipped` rather than folded into a success. */ export declare function resourceRemoteSyncAsync(solutionPath: string | undefined, resourceKey: string, options?: ResourceRemoteSyncOptions): Promise;