/** * The guided first run of `cleo login nexus` (T13102, owner decision * 2026-10-02: onboarding = A + B + C' + D, so that `cleo login` is the only * setup step in practice). It runs after a successful sign-in and never fails * it: every problem becomes a state, a warning and the exact next command. * * - **Inside a CLEO project this device has not linked**: offer "link and * back up now". With consent `yes` (`--yes`) it links the project through * {@link linkProjectToNexus} (the same path as `cleo project link`, so the * project key created at registration comes with it) and then takes the * first encrypted backup through {@link pushNexusVault}. With `prompt` (a * terminal) it asks first. With `never` (a non-interactive run: an agent) * it never asks and reports the exact next command. * - **Inside an unlinked project the cloud already backs up**, from another * device, and this copy never synced (a fresh clone on a new machine: the * project id is tracked in git): a backup would be refused as behind, so * the offer is to restore that backup here ({@link restoreNexusVault}, then * the same link), under the same consent rules. * - **Inside a project linked and attached from this device**: nothing to do. * - **Outside a CLEO project**: list the account's projects by name * ({@link listNexusNamedProjects}) with the exact `cleo cloud restore` * command for each one this machine can restore. * - **A read-only device, or device credentials off**: skipped. * * Every printed command carries `--api-url` when the origin is not the * default. No function here logs, prompts or prints: the caller supplies * `confirm` and `onStep`. * * @task T13102 * @epic T12322 */ import type { CloudPushResult, CloudRestoreResult, NexusFirstRunResult, NexusFirstRunState, NexusProjectLinkResult } from '@cleocode/contracts'; import { type NexusLinkOptions } from './nexus-link.js'; import { type NexusNamedProjectsOptions, type NexusNamedProjectsResult } from './nexus-project-names.js'; import { type NexusVaultCommandOptions, type NexusVaultRestoreOptions } from './nexus-vault.js'; import type { NexusVaultOptions } from './nexus-vault-keys.js'; /** The question a terminal is asked before linking and backing up. */ export declare const NEXUS_FIRST_RUN_QUESTION = "This project is not linked to Cleo Nexus. Link it and back it up now (encrypted)?"; /** The question a terminal is asked before restoring a backup this copy never synced. */ export declare const NEXUS_FIRST_RUN_RESTORE_QUESTION = "Cleo Nexus holds a backup of this project from another device. Restore it here now?"; /** Warning code: linking the project failed. */ export declare const W_NEXUS_FIRST_RUN_LINK = "W_NEXUS_FIRST_RUN_LINK"; /** Warning code: the first backup failed. */ export declare const W_NEXUS_FIRST_RUN_BACKUP = "W_NEXUS_FIRST_RUN_BACKUP"; /** Warning code: restoring the cloud's backup failed. */ export declare const W_NEXUS_FIRST_RUN_RESTORE = "W_NEXUS_FIRST_RUN_RESTORE"; /** Warning code: the account's projects could not be listed. */ export declare const W_NEXUS_FIRST_RUN_PROJECTS = "W_NEXUS_FIRST_RUN_PROJECTS"; /** Warning code: a non-fatal problem the link reported. */ export declare const W_NEXUS_FIRST_RUN_LINK_NOTE = "W_NEXUS_FIRST_RUN_LINK_NOTE"; /** * Whether the first run may act: `yes` does it, `prompt` asks through * `confirm`, `never` only reports the next command. `unattended` (a * non-interactive run outside CI, e.g. an agent: T13288) takes the safe * default of each question without asking — so it links and backs up an * unlinked project, but never restores over this copy (that question * defaults to no) and reports the restore command instead. */ export type NexusFirstRunConsent = 'yes' | 'prompt' | 'unattended' | 'never'; /** A step the first run is about to take (for progress lines). */ export type NexusFirstRunStep = 'link' | 'backup' | 'restore' | 'projects'; /** What {@link NexusFirstRunOptions.cloudBackup} is asked about. */ export interface NexusCloudBackupQuery extends NexusVaultOptions { /** API origin. */ apiUrl: string; /** The project's root on this machine. */ projectRoot: string; /** The server's project id (the tracked local id, or the link's remote id). */ projectId: string; } /** Options of {@link runNexusFirstRun}. */ export interface NexusFirstRunOptions extends NexusVaultOptions { /** `yes` (`--yes`), `prompt` (a terminal) or `never` (non-interactive). */ consent: NexusFirstRunConsent; /** * Asks a yes/no question (`prompt` only); `defaultYes` is what an empty answer means * (yes for link and back up, no for a restore). Without it, `prompt` acts as `never`. */ confirm?: (question: string, defaultYes: boolean) => Promise; /** The device login enrolled, to tell projects attached here from others. */ deviceId?: string | null; /** The device signed in with the read-only profile: it cannot link or back up. */ readOnly?: boolean; /** Called before each step (progress lines). */ onStep?: (step: NexusFirstRunStep) => void; /** Link (tests); defaults to {@link linkProjectToNexus}. */ link?: (opts: NexusLinkOptions) => Promise; /** Push (tests); defaults to {@link pushNexusVault}. */ push?: (opts: NexusVaultCommandOptions) => Promise; /** Restore (tests); defaults to {@link restoreNexusVault}. */ restore?: (opts: NexusVaultRestoreOptions) => Promise; /** Unsynced-backup check (tests); defaults to {@link hasUnsyncedNexusBackup}. */ cloudBackup?: (query: NexusCloudBackupQuery) => Promise; /** Project list (tests); defaults to {@link listNexusNamedProjects}. */ listProjects?: (opts: NexusNamedProjectsOptions) => Promise; } /** * A first-run result with every field at its empty value. * * @param state - How it ended. * @param fields - Fields to set. * @returns The result. */ export declare function nexusFirstRunResult(state: NexusFirstRunState, fields?: Partial>): NexusFirstRunResult; /** The commands a first run names (see {@link nexusFirstRunCommands}). */ export interface NexusFirstRunCommands { /** Link the current project, then push its first backup. */ linkAndBackUp: string; /** Link the current project, then push it as a labelled fork over a newer cloud head. */ linkAndForkPush: string; /** Push the current project. */ push: string; /** Pull the cloud's newest snapshot into the current project. */ pull: string; /** List the account's projects. */ projects: string; /** Restore a project's backup into a directory. */ restore: (projectId: string, root: string) => string; } /** * The commands a first run names, with `--api-url` when the origin is not the default. * * @param apiUrl - API origin. * @returns The link-and-back-up, push, pull, list and restore commands. */ export declare function nexusFirstRunCommands(apiUrl: string): NexusFirstRunCommands; /** * Whether Cleo Nexus holds a backup of the project that this copy never * synced: the project is registered with a head snapshot (E14, a `GET`), and * the vault state records no sync of its stream from this project root. Any * failure answers `false`, so the run falls back to link and back up. * * @param query - API URL, project root and id, stores and test overrides. * @returns `true` when a restore, not a backup, is the right first step. */ export declare function hasUnsyncedNexusBackup(query: NexusCloudBackupQuery): Promise; /** * The guided first run after `cleo login nexus` signed in. Never throws for a * flow failure: the result's state, warnings and next command describe it. * * @param opts - Consent, prompt, device id, profile, API URL, stores and test overrides. * @returns How it ended. * @throws {NexusAccountError} `E_NEXUS_INVALID_API_URL` only (login has already checked it). */ export declare function runNexusFirstRun(opts: NexusFirstRunOptions): Promise; //# sourceMappingURL=nexus-first-run.d.ts.map