/** * A profile name is ONE path component: LOWER-case letters, digits, dot, * underscore and hyphen, 1–64 of them. `..` matches this charset (it is two * dots and nothing else), which is exactly why `resolveProfileName`'s * dot-segment rejection is not redundant. * * This describes the CANONICAL form. NTFS and default APFS fold case, so `Work` * and `work` are ONE directory on those filesystems; `resolveProfileName` * therefore lower-cases what the caller typed and uses the folded result, rather * than rejecting a name the caller means perfectly well. The fold is reported * back so it is never silent. */ export declare const PROFILE_NAME_RE: RegExp; /** Bound a caller-supplied name before it is embedded in a message. */ export declare function cappedEcho(raw: string): string; /** `/.peaks/web-profiles//`. The name must be resolved first. */ export declare function webProfileDir(name: string): string; /** * Validate a caller-supplied `--profile` and return the CANONICAL name — the * input lower-cased, which is the one name the filesystem will actually store. * `--profile Work` resolves to `work`. * * The fold is deliberate (user decision, 2026-09-10) and is never silent: the * call site compares what it typed with what came back and reports the * difference. What has no sensible canonical form is still refused — see * `hasTrailingDotOrSpace`. * * Two refusals are DELIBERATE rather than incidental (S4 repair, security S6): * * - a LEADING dot is refused, because it makes `folded.split('.')[0]` empty. * `.con` is the Windows device under a name the stem test cannot see, and * `..foo` is a dot segment that `PROFILE_NAME_RE` accepts — it used to be * stopped by `assertUnder` instead, which surfaced `WEB_PATH_ESCAPE` under * the wrong code. Both now carry this function's own message. * - the caller's input is echoed CAPPED, like the CLI's gate refusal, so a * huge `--profile` cannot be reproduced whole in a message. * * Throws `WEB_PROFILE_NAME_INVALID`, and returns the NAME rather than a path so * a call site cannot mistake one for the other. */ export declare function resolveProfileName(raw: string): string; /** * `/.peaks/web-profiles//storageState.json` — the persisted * artifact, and the only thing `login` writes. */ export declare function loginStorageStatePath(name: string): string; export interface WebLoginOutcome { readonly ok: boolean; /** * `''` when `ok` AND the capture verified; a code when the outcome is a * failure, and also when a write landed but could not be read back — an * `ok: true` with `bytes > 0` is not the same thing as a usable profile. */ readonly code: string; readonly message: string; readonly profile: string; readonly storageStatePath: string; /** Size of the persisted file. 0 whenever nothing was written. */ readonly bytes: number; /** Cookie/origin COUNTS only — never the values (see `readStateCounts`). */ readonly cookies: number; readonly origins: number; /** Never silent: a teardown or read-back problem lands here (S1's F1). */ readonly warnings: readonly string[]; } export interface WebLoginOptions { /** A name that already passed `resolveProfileName`; re-validated here. */ readonly profile: string; /** * Called once, with the headed browser already open and before the wait * begins. IO belongs to the CLI layer, so the human instruction ("log in, * then close the window") is composed there. */ readonly announce: () => void; /** Defaults to `LOGIN_TIMEOUT_MS`. A test shortens it; nothing else does. */ readonly timeoutMs?: number; } /** * Open the headed browser, read the session into memory while the user works, * and persist it when the user closes the window. * * Everything that happens once the browser is up comes back as `ok: false` with * a code rather than a throw. A failure BEFORE that point — an invalid name, an * unresolvable Playwright, a launch that will not start — does throw, because * there is no browser to tear down and no outcome to describe; the CLI renders * it with the same code and the same envelope shape, so the caller sees one * contract either way. */ export declare function runHeadedLogin(options: WebLoginOptions): Promise;