/** Flow L13 — the start block. */ export interface StartBlockInput { projectName: string; orgName: string; /** The forward target, printed BEFORE the URL so the 502 advisory matches it. */ targetUrl: string; url: string; /** Pre-rendered QR rows, or undefined for non-TTY / piped / --no-qr. */ qr?: string[]; expiresInHours: number; } export declare function startBlock(i: StartBlockInput): string[]; /** * Flow L14 — not signed in. The B2/B21 line, and the one screen that must not * feel like a wall. * * Line 1 is f1's exact string, so a creator meeting this gate in a second * command reads one product. The last paragraph is the most important copy in * f3's CLI: the overview commits that the local room stays a real room, and a * creator told only "sign in" has just been told the product does not work * without an account, which is false. It is offered as a CAPABILITY, not as * consolation — no "unfortunately", no "you can still". */ export declare function notSignedIn(): string[]; /** Flow L16 — `--viewer`, a second terminal, not a second preview. */ export declare function followingBlock(label: string, descriptor: string): string[]; export declare function followingFooter(): string[]; /** * Flow L18 — their dev server is down. * * `!`, not `✗`, and the command does not exit: this is the most common failure * in the whole feature and it is entirely the creator's to fix. Ending the * preview would take away the link and force a re-scan of every phone in the * room over an `npm run dev` they forgot. * * The middle line splits the wire in two, because the creator's first instinct * on a 502 is to suspect us. */ export declare function originDown(targetUrl: string): string[]; /** Flow L19 — the creator's own network drops. */ export declare function reconnecting(): string[]; export declare function reconnected(): string[]; export declare function graceExhausted(): string[]; /** * The drop past the cap. The rule is stated AT THE MOMENT IT BITES and never * before — explaining it up front would be a limit the creator carries through * every healthy session. * * THE NUMBER IS DELIBERATELY NOT NAMED, and that reverses an earlier draft which * read "for the third time" and "up to three times… a fourth time". Three * reasons, in the order they decided it: * * 1. At three the numeral WAS the explanation — a creator could recognise their * own three drops. At ten nobody has been counting, so the numeral states a * tally the creator never kept and cannot audit (`graceUsed` is not * observable from the CLI), and an orienting sentence becomes one that * invites them to argue with the tally. What is left doing the work is the * STATE, not the count: the connection kept dropping. * 2. Copy that spells a config value is a SECOND ENCODING of that constant. The * cap has already moved once mid-build (3 → 10) and this copy went false * with nothing failing. Not naming it removes the class of bug rather than * fixing one instance. * 3. The remedy is what the creator needed and the old copy omitted it — the * block ended on "so the link is gone" with no next command, breaking f3's * own rule. It is now byte-identical to graceExhausted's, because from the * creator's position the two endings are the same event with a different * cause. * * "but only so many times" is a real limit stated without a value: a bound * exists, it is finite, it was reached. If the cap is raised or lowered again the * sentence is still true, which is the property the previous version lacked. */ export declare function graceCapReached(): string[]; /** * a. The creator stops it (SIGINT). The connected count appears on the stopping * line ONLY when there are any, because the creator is about to blank someone's * screen and has a half-second to reconsider. It does NOT prompt — a * confirmation on Ctrl-C is the wrong trade in a command a creator stops fifty * times a day, and it would break the unattended agent path (B20). */ export declare function stopping(connected: number): string; export declare function stopped(ranMs: number, totalConnections: number): string[]; /** * `stopped` arriving on a 410 — someone ended the preview from somewhere else. * * NOT `stopped()` with a different first line, and the difference is not tone. * `stopped()` prints `Ran … · N viewers total` from the timer and counter THIS * process held. A window that was not the actor holds neither, so it would * render `Ran 0m 00s · 0 viewers total` for a preview that ran three hours to a * roomful of phones. A fabricated zero is worse than an omitted line, so this * screen carries no stats at all. * * The claim is exactly what the wire supports: `stopped` is produced by one * route, authorized by the compound key {_id, userId}, so the actor is ALWAYS * the same account as the reader. Never a teammate, never an admin. It does not * say WHICH window, because another terminal, another machine and a future * console control are all the same 410. * * `✓`, not `✗`: someone with the authority to stop it stopped it. */ export declare function stoppedElsewhere(): string[]; /** * `disconnected` — the connection closed and the session did not come back. * * This deliberately UNDER-CLAIMS. `disconnected` is the DEFAULT arm of the * edge's reason mapping: a clean socket close, a crashed harness, a laptop lid, * an edge restarting under a deploy, and a genuinely dropped network all land * on this one value. Naming any of them is the over-claim that produced the * abandoned→hard_max defect, so the copy states the one certain fact and then * says out loud that it cannot narrow it. * * "or something on our side" stays. Removing it turns an honest unknown into a * list of the creator's own failures. * * NOT merged with graceExhausted(), though they look adjacent: that screen is * about the CLI's OWN observation — it watched the link go and tried to get it * back, so "check your network" is earned. This one is a reason REPORTED to a * process that may not have witnessed the disconnect, and its target case is * the window that still looks healthy. Merging reinstates the original defect. */ export declare function endedDisconnected(): string[]; export declare function formatElapsed(ms: number): string; /** * b. The 12-hour hard maximum, warned at 30 minutes. * * The warning names the wall-clock time AND the interval — the first is what a * creator plans a demo around, the second is what they feel — and it states the * cost of restarting, which is the new link. A creator with a printed QR on a * desk needs that sentence 30 minutes early, not at the ceiling. */ export declare function hardMaxWarning(clockTime: string, minutesLeft: number): string[]; /** * `✓`, not `✗`. Nothing failed; the preview did exactly what the start block * said it would 12 hours earlier, and marking it as a failure would teach the * creator that the ceiling is a fault. This is the ONLY place in f3 that points * at f4, and it belongs here: it is the exact moment a creator first wants an * address that lasts. */ export declare function hardMaxReached(): string[]; /** c. Superseded — the terminal that LOST. */ export declare function supersededLoser(): string[]; /** * Re-running `vincentt preview` on a folder that already has one attaches to it * rather than minting a second — but a caller who is not SHOWN the link cannot * tell the difference between "attached" and "failed to give me a URL". The * reported behavior was an agent re-running preview until it saw a link, and * each of those re-runs superseded the previous session: the link really did * keep changing, because the attach never printed one. * * The URL renders bare on its own line, matching the start block, so anything * scraping for a link finds it in the same shape either way. */ export declare function attachedToRunning(url: string, expiresAt?: string): string[]; /** * c. Superseded — the terminal that WON. This sits ABOVE the `✓ Preview is live` * block so the consequence is read before the URL is copied. */ export declare function supersededWinner(): string[]; /** * d. The fail-closed drain. TWO causes, one screen each, deliberately NOT * merged, because the remedies differ: one is "find out who you are", the other * is "try again". Neither names the edge, the API, or an outage — a creator * cannot act on that and the retry is the whole of the advice. */ export declare function endedUnreachable(orgName: string): string[]; export declare function endedUnconfirmed(): string[]; /** * e. Abandoned — this machine stopped checking in (the 30-minute heartbeat- * silence flip, `D-Abandoned-sessions-are-judged-on-heartbeat-silence-alone`). * * THIS ENDING EXISTS BECAUSE REPORTING IT AS ANY OF THE OTHER FOUR WOULD BE A * FALSE STATEMENT ABOUT OUR OWN BEHAVIOUR. The nearest neighbour is the hard max, * and it is the one that must never be borrowed: a session flipped at minute 30 * has not reached a 12-hour ceiling, and that ending is a `✓` saying the preview * did exactly what it promised. Rendering it here would tell a creator their 12 * hours elapsed when 30 minutes did. * * Written for the UNCOMMON reader. In the common case the CLI is dead and nobody * sees this; the screen exists for the creator whose heartbeat channel wedged * while the process lived, who is at a terminal that still looks alive and may * have a working tunnel and a running app in front of them. * * - "this machine", not the network and not the tunnel: `heartbeatAt` measures * the creator's check-in and nothing else. "You lost connection" would be * L19's event and would send them to their router; "the tunnel dropped" would * be false in the exact case this screen is for. "This machine" also * disambiguates in a two-machine org. * - "Nothing is wrong with your project" is load-bearing, not filler. This * ending arrives with no visible cause, and the first thing a creator does * with an unexplained ending is look for a fault in their own work. * - NO duration and no "30 minutes": the interval is a server-side threshold * the creator cannot observe or plan around, and naming it invites the same * drift the grace copy just removed. * - The remedy is `vincentt preview` and there is NO "resume": by the time this * fires the session's resume tokens are gone, so offering a resume would be * offering something that cannot work. */ export declare function endedAbandoned(): string[]; /** * The 2 GiB soft warning, printed ONCE. It names the ceiling (a warning without * a number is only anxiety), names the cause (a full reload per edit is * genuinely surprising), and names the remedy WITH ITS COST — the new link, * which is otherwise learned the hard way. */ export declare function egressSoft(): string[]; export declare function egressHard(): string[]; /** * The mint limit. No remaining-attempt count and no policy text. The second * paragraph is load-bearing: the person most likely to hit 10/hour is someone * restarting in a loop who has not realised a running preview already serves * them, and that sentence is the actual fix. */ export declare function mintRateLimited(retryAfterSec: number): string[]; /** * The wait is rounded and hedged because the number comes from a token bucket * that keeps refilling. "about 20 minutes" that turns out to be 19 is fine; * "20 minutes" that turns out to be 21 reads as a broken promise. */ export declare function approxWait(seconds: number): string; /** The conflict a supersede lost (409). Rare: the mint supersedes first. */ export declare function previewConflict(): string[];