/** * One-shot migration: import the legacy `${CLEO_HOME}/anthropic-key` flat file * into the unified credential pool as a `legacy-flat-key` entry. * * Part of `E-CONFIG-AUTH-UNIFY` Epic E1 (T9406 / T-E1-4). The legacy flat key * file is the "tier 4b" entry in the current 6-tier resolver in * `credentials.ts`. Once imported into the pool, the resolver's tier-3 * (`cred-file`) lookup will pick it up — so post-E2 we can collapse the * tier-4b branch entirely without losing any operator's previously-stored * key. * * ## Behavior * * On `importLegacyFlatAnthropicKey()` (idempotent): * * 1. If the migration marker `${CLEO_HOME}/.imported-legacy-flat-key` exists, * return immediately (`status: 'marker-present'`). * 2. If the pool already contains an `anthropic` entry with * `label === 'legacy-flat-key'`, write the marker and return * (`status: 'already-imported'`). * 3. If `${CLEO_HOME}/anthropic-key` does not exist, write the marker and * return (`status: 'no-flat-file'`). Avoids re-stating the file on * every CLI invocation. * 4. If the flat file exists but its trimmed content is empty, write the * marker and return (`status: 'empty-flat-file'`). We do NOT rename an * empty file — leave it for the operator to inspect / delete. * 5. Otherwise: call `addCredential()` with the trimmed key, then rename * the flat file to `anthropic-key.pre-e1-bak`, then write the marker. * Returns `status: 'imported'`. * * ## Atomicity contract * * The two side-effects we care about — (a) the pool entry insert and * (b) the flat-file rename — are sequenced so a failure at (b) leaves the * pool entry in place AND no marker is written. The next run will then * skip the insert (via the `getCredentialByLabel` check in step 2 above) * but still attempt the rename. This avoids a half-done state where the * marker exists but the original flat file is still discoverable by the * tier-4b resolver branch (which would re-import it on the next pool * rebuild). * * If `addCredential()` itself throws, nothing is renamed and no marker * is written — the next invocation retries cleanly. * * @module llm/legacy-flat-key-import * @task T9406 * @epic E-CONFIG-AUTH-UNIFY */ /** * Canonical label assigned to the imported entry. * * Constant rather than parameterized — the resolver collapse in E2 keys * its behavior off this exact label, so it MUST remain stable. */ export declare const LEGACY_FLAT_KEY_LABEL = "legacy-flat-key"; /** * Filename suffix used when renaming the original flat file post-import. * * Kept identical to the convention used by the T310 conduit migration * (`.pre-t310.bak`) for cross-codebase greppability. */ export declare const LEGACY_FLAT_KEY_BAK_SUFFIX = ".pre-e1-bak"; /** * Filename of the migration marker inside `getCleoHome()`. Existence of * this file (any content) is sufficient to short-circuit the migration. */ export declare const LEGACY_FLAT_KEY_MARKER = ".imported-legacy-flat-key"; /** * Outcome of a single migration attempt. * * - `imported` — flat file read, pool entry added, file renamed, * marker written * - `already-imported` — pool already had a `legacy-flat-key` entry; * marker written so we never reach this branch * again * - `no-flat-file` — `${CLEO_HOME}/anthropic-key` does not exist; * marker written * - `empty-flat-file` — flat file existed but trimmed content was empty; * marker written; file is NOT renamed * - `marker-present` — short-circuit from the first idempotency check * * @task T9406 */ export type LegacyFlatKeyImportStatus = 'imported' | 'already-imported' | 'no-flat-file' | 'empty-flat-file' | 'marker-present'; /** * Result returned by `importLegacyFlatAnthropicKey()`. * * `bakPath` is populated only when the rename actually occurred (i.e. * `status === 'imported'`). * * @task T9406 */ export interface LegacyFlatKeyImportResult { /** Outcome category — see `LegacyFlatKeyImportStatus`. */ status: LegacyFlatKeyImportStatus; /** Absolute path of the original flat key file (whether or not it existed). */ flatPath: string; /** Absolute path of the renamed backup, or null if no rename happened. */ bakPath: string | null; /** Absolute path of the marker file (always populated post-call). */ markerPath: string; } /** * Import the legacy `${CLEO_HOME}/anthropic-key` flat file into the * credential pool, exactly once per CLEO home directory. * * Idempotent — safe to call from any bootstrap path on every CLI * invocation. The marker file guarantees O(1) cost on warm runs. * * Never throws. All errors are caught and surfaced through the structured * logger; the resolver fallback chain still works. * * @returns A `LegacyFlatKeyImportResult` describing the outcome. * * @task T9406 */ export declare function importLegacyFlatAnthropicKey(): Promise; /** * Run {@link importLegacyFlatAnthropicKey} at most once per Node process. * * Fire-and-forget: the credentials resolver is synchronous, but the import * is async (the credential-store API is async). Callers MUST NOT await * this — the helper is fully idempotent and the marker / pool-entry checks * ensure later invocations observe the imported entry without re-running. * * Errors are caught and dropped on the floor (the underlying helper already * logs through the structured logger). Returning a no-op promise keeps the * call site uniform with {@link ensureGlobalConfigMigrated} from * `global-config-migration.ts`. * * Wired into `resolveCredentials()` so a stale install gets its legacy flat * key promoted into the credential pool on first credentials read. * * Use {@link _resetLegacyFlatKeyImportLatch} in tests to re-arm the latch. * * @public * @task T9407 */ export declare function ensureLegacyFlatAnthropicKeyImported(): void; /** * Reset the in-process import latch. Test-only — use in `beforeEach` so each * test re-runs the import with its own fresh `CLEO_HOME` / `XDG_DATA_HOME` * overrides. * * @internal * @task T9407 */ export declare function _resetLegacyFlatKeyImportLatch(): void; //# sourceMappingURL=legacy-flat-key-import.d.ts.map