/** * credential-sync.ts β€” persist the credential bundle `hula launch` / `hula plan` * send to hula-server as the project's stored credential set, so the dashboard * and the PWA can launch without the user uploading a `.env` or typing a token. * * The bundle is produced by `buildRemotePlanningBundle` (the exact set a launch * sends), so the saved set is byte-for-byte what a launch would transmit. The * sync is best-effort: `syncCredentialSet` never throws, so a sync problem can * never block or fail a launch. Values are never printed β€” only hints. */ import type { Config } from '../types/config.schema.js'; import { type RemotePlanningBundle } from './planning-credentials.js'; import { type ApiCredentialSet } from '../services/api/HulaApiClient.js'; /** Default credential-set name when `--name` is not given. */ export declare const DEFAULT_CREDENTIAL_SET_NAME = "default"; /** * Verbatim explanation shown above the opt-in question (in `hula init`, * `hula login` and `hula init web`). States plainly that enabling web + phone * planning stores some secrets permanently, encrypted, whereas normally secrets * live only while a launched plan is in flight. */ export declare const WEB_PLANNING_EXPLANATION = "\uD83C\uDF10 Web and phone planning\nTo plan from the HubLaunch dashboard or your phone, HubLaunch must keep some secrets\npermanently, encrypted, in its database: your GitHub token, your provider key, the\nenv vars you forward to the sandbox and your update-notification settings (the\nSlack/webhook URL and name tag). Normally HubLaunch keeps your secrets only while a\nlaunched plan is in flight (until its PR is merged). Enabling this stores them until you\nturn it off with `hula init web disable`, which also deletes them from HubLaunch."; /** The opt-in question (default yes). */ export declare const WEB_PLANNING_PROMPT = "Enable planning from the web dashboard and your phone?"; /** * Inline comment written next to `saveCredentials` in the generated config. * Documents what each value means and how to change it later. */ export declare const SAVE_CREDENTIALS_CONFIG_COMMENT = "// Web + phone planning. true = keep your GitHub token, provider key, forwarded env vars and update-notification settings (Slack/webhook URL and name tag) permanently (encrypted) on HubLaunch as your \"default\" credential set, refreshed on every launch. false = secrets are kept only while a launched plan is in flight (until its PR is merged). Change any time: hula init web | hula init web disable"; export type SyncResult = { status: 'synced'; created: boolean; name: string; hint: string; /** Names (never values) of the env vars now stored on the set, sorted as the server returns them. */ envVarKeys: string[]; /** Non-fatal advisories to print after the line (W1/W1-hook/W2/W3). */ warnings: string[]; } | { status: 'skipped'; reason: 'disabled' | 'no-api-key' | 'no-github-token' | 'no-provider' | 'server-unsupported' | 'error'; message?: string; }; export interface SyncCredentialSetArgs { repoRoot: string; config: Config; serverUrl: string; apiKey?: string; project: string; name?: string; /** Pre-resolved bundle (launch passes the one it already built). */ bundle?: RemotePlanningBundle; /** * Names of the env vars a beforeLaunch hook contributed in THIS launch. * These are per-launch and never part of the stored set the user manages, so * they are suppressed from the W3 "removed" advisory. Only `hula launch` * passes this; `hula credentials sync` and `hula plan` run no hook and leave * it empty, so every removed key there is user-visible and gets named. */ hookEnvVarNames?: string[]; /** * Skip the `config.saveCredentials` gate. Automatic callers (launch, plan) * leave this false so the sync only runs when enabled; the explicit * `hula credentials sync` command sets it true to run regardless. */ force?: boolean; } /** * Mask a secret the same way the server does for its hints: first 4 characters, * an ellipsis, then the last 4. Short values collapse to `…` so no meaningful * amount of the secret is ever revealed. */ export declare function hintFor(value: string): string; /** * Persist the credential set. Best-effort: resolves to a `SyncResult` and never * throws. Builds the bundle with `buildRemotePlanningBundle` when the caller did * not supply one, maps the bundle's single provider to `providerKeys`, and * converts forwarded env vars to the server's `{ key, value, secret }[]` shape. */ export declare function syncCredentialSet(args: SyncCredentialSetArgs): Promise; /** * One line summarising the result, hint-only. Never prints secret values. * synced β†’ `πŸ” Credentials saved to HubLaunch as "default" (GitHub ghp_…k3Q9) Β· 3 env vars: A, B, C` * skipped β†’ `πŸ” Credentials not saved: ` */ export declare function formatSyncLine(result: SyncResult): string; /** * The non-fatal advisories to print after a synced line. `[]` for a skipped * result (nothing was stored, so there is nothing to warn about). */ export declare function formatSyncWarnings(result: SyncResult): string[]; /** * Print `formatSyncLine(result)` through the logger: a synced result is plain * info, a skipped one is a red `logger.error` line so a failed sync (e.g. an * expired API key) is not lost among the surrounding output. Each advisory * (W1/W1-hook/W2/W3) follows the synced line as a `logger.warning`. */ export declare function logSyncLine(result: SyncResult): void; /** * Log a sync result from the onboarding (`hula login` / chained `hula init`) * path, where a missing provider key is the common, non-alarming case β€” so, * unlike `logSyncLine`, it does NOT print a red error line for every skip: * synced β†’ info (the saved line) * no-provider β†’ info ("will be saved on your first launch") * disabled β†’ nothing (login only calls this when enabled; defensive) * server-unsupportedβ†’ debug only * everything else β†’ warning (so a genuine failure is still visible) */ export declare function logOnboardingSyncLine(result: SyncResult): void; /** Re-export for callers that render a list of stored sets. */ export type { ApiCredentialSet }; //# sourceMappingURL=credential-sync.d.ts.map