import { HudVisibility } from './constants/hud-use.js'; /** Bumped only for a change an older reader would MISREAD. A new field is not one. */ export declare const PLATFORM_LINK_VERSION = 1; /** What a daemon can do for the platform, as it reports it. */ export declare const LinkCapability: { /** Reads a `DriveSpec`, and reports what it applied and what it ignored. */ readonly DRIVE_SPEC: "drive-spec"; /** Drives the person's own open tab. */ readonly TARGET_TAB: "target:tab"; /** Opens the app in a browser of its own with no window. */ readonly TARGET_HEADLESS: "target:headless"; /** Opens the app in a browser window the person can watch. */ readonly TARGET_HEADED: "target:headed"; /** Shows, hides or removes the HUD on the page it drives. */ readonly HUD: "hud"; /** Runs a drive the platform orchestrates, one batch of tool calls at a time. */ readonly TOOL_SESSION: "tool-session"; /** Sends pictures of the page while it drives. */ readonly FRAMES: "frames"; }; export type LinkCapability = (typeof LinkCapability)[keyof typeof LinkCapability]; /** Where a drive runs. */ export declare const DriveTarget: { /** A tab the person already has open. Their HUD shows it happening. */ readonly TAB: "tab"; /** A fresh browser context with no window. */ readonly HEADLESS: "headless"; /** A fresh browser window on the person's screen. */ readonly HEADED: "headed"; }; export type DriveTarget = (typeof DriveTarget)[keyof typeof DriveTarget]; /** Who decides each step of a drive. */ export declare const DriveMode: { /** The daemon's own Harness plans and judges it. What every daemon before this link did. */ readonly LOCAL: "local"; /** The platform decides every step over a tool session; the daemon only runs tools. */ readonly PLATFORM: "platform"; }; export type DriveMode = (typeof DriveMode)[keyof typeof DriveMode]; /** Why a field of a spec was not applied. */ export declare const SpecIgnoredReason: { /** This daemon does not know the field: the platform is newer. */ readonly UNKNOWN: "unknown"; /** The value did not read as the field's type. */ readonly INVALID: "invalid"; /** Known and valid, but this machine cannot do it right now (no browser, no HUD on the page). */ readonly UNAVAILABLE: "unavailable"; }; export type SpecIgnoredReason = (typeof SpecIgnoredReason)[keyof typeof SpecIgnoredReason]; export interface DriveSpec { target?: DriveTarget; mode?: DriveMode; /** The address to open, for a target that opens one. Absent: the app's own last address. */ url?: string; hud?: HudVisibility; persona?: string; maxSteps?: number; /** Whether pictures of the page may leave the machine. */ record?: boolean; /** A plan the platform saved: run it as it stands instead of asking for a new one. */ plan?: string; /** * A person started this run (Run plan, Re-verify, Run suite) and so acknowledged the saved flows' * own destructive steps: their replays may take them. A fresh action the model decides keeps the * guard whatever this says. */ confirmDangerous?: boolean; } export interface SpecIgnored { field: string; reason: SpecIgnoredReason; /** Why, in a person's words, when there is more to say than the reason. */ detail?: string; } /** * Read a spec as far as it can be read. Never throws: a field that does not validate, or that this * daemon does not know, is reported in `ignored` and the rest still apply. */ export declare function parseDriveSpec(raw: unknown): { spec: DriveSpec; ignored: SpecIgnored[]; }; /** What a daemon did with a spec, sent back with the drive's result or its first session ask. */ export interface DriveApplied { target: DriveTarget; mode: DriveMode; url?: string; hud?: HudVisibility; /** The tab the drive ran in. */ sessionId?: string; } /** One tool call the platform asks the daemon to run. */ export interface ToolSessionCall { seq: number; tool: string; args: Record; } /** How one call went, as the daemon ran it. `result` is the tool's own answer, unedited. */ export interface ToolSessionResult { seq: number; ok: boolean; result?: unknown; error?: string; ms: number; } /** The platform's answer to a session ask: the next calls, or that the drive is over. */ export interface ToolSessionReply { calls: ToolSessionCall[]; done: boolean; } /** Bounds a daemon holds a tool session to, whatever the platform asks. */ export declare const TOOL_SESSION_LIMITS: { /** Calls one drive may make in all: a loop on the platform must not drive forever. */ readonly MAX_CALLS: 1000; /** Calls taken from one answer; the rest are not run. */ readonly MAX_BATCH: 25; /** * Times one ask is sent again after the network or the platform failed it. The SAME ask, under * the same `ask` number, so the platform answers it once: a resend never advances the drive twice. */ readonly RETRIES: 4; /** The first wait before asking again; it doubles each time (0.5s, 1s, 2s, 4s). */ readonly RETRY_BASE_MS: 500; }; /** * Whether an ask that came back with this status is worth sending again: the platform or the network * failed it (5xx, 429, 408). A refusal (4xx) is the platform's answer, and asking again changes nothing. */ export declare const sessionAskRetryable: (status: number) => boolean; /** * Read the platform's answer. Never throws: an answer that does not read is "done", because a drive * that cannot understand its orders must stop rather than guess. A call that does not read is * dropped; the platform sees no result for its `seq` and decides what that means. */ export declare function parseToolSessionReply(raw: unknown): ToolSessionReply; /** How much a platform notice matters to the person reading it. */ export declare const LinkNoticeLevel: { readonly INFO: "info"; readonly WARN: "warn"; /** Their Reticle is older than what the platform can use: what to run to update it. */ readonly UPDATE: "update"; }; export type LinkNoticeLevel = (typeof LinkNoticeLevel)[keyof typeof LinkNoticeLevel]; /** * Something the platform tells the person through their daemon: "update Reticle to drive with every * option". The one way a platform reaches a daemon it cannot change, so it is kept to a sentence. */ export interface LinkNotice { level: LinkNoticeLevel; text: string; url?: string; } export declare const LINK_NOTICE_MAX = 3; export declare const LINK_NOTICE_TEXT_MAX = 300; /** Read the platform's notices; one that does not read is dropped, never shown half-read. */ export declare function parseLinkNotices(raw: unknown): LinkNotice[]; /** The platform's paths the daemon calls, all with its machine key. */ export declare const LinkPath: { /** The apps this machine has connected; answered with apps to open and whether a drive waits. */ readonly APPS: "/v1/harness/local-apps"; /** The next drive for this project, or null. */ readonly NEXT_DRIVE: "/v1/harness/local-drives/next"; /** How a drive ended. */ readonly driveResult: (id: string) => string; /** A picture of the driven page. */ readonly driveFrames: (id: string) => string; /** One turn of a tool session: results in, next calls out. */ readonly driveSession: (id: string) => string; }; /** * What a daemon adds to each local-apps report so the platform can say what an app is missing and * why a page never connected. Every key is additive: a platform that predates one ignores it. */ export declare const LinkReportKey: { /** Per app: the channels its page announced in its HELLO. */ readonly CHANNELS: "channels"; /** Per app: instrumentation gaps its verdicts recorded, deduped by kind + missing, newest first. */ readonly GAPS: "gaps"; /** Per app: the framework adapters its page announced. */ readonly ADAPTERS: "adapters"; /** * Per app: coverage capabilities that do not apply to it (`CoverageCapability` values, see * `NotApplicableSchema`), excluded from both sides of the coverage score. Always sent, empty when * every capability applies. */ readonly NOT_APPLICABLE: "notApplicable"; /** Top level: dev servers listening on this machine that no Reticle page has connected from. */ readonly DEV_SERVERS: "devServers"; /** Top level: the last page handshake this daemon refused, and why. */ readonly HELLO_FAILURE: "helloFailure"; /** Top level: `.reticle` folders holding runs that never reached the platform. */ readonly UNSYNCED: "unsynced"; }; /** How many recorded gaps one app reports. */ export declare const LINK_APP_GAPS_MAX = 20; /** One recorded instrumentation gap, as an app report carries it. */ export interface LinkAppGap { kind: string; missing: string; fix: string; seenAt: number; } /** A dev server listening on localhost with no connected Reticle page. */ export interface LinkDevServer { url: string; port: number; } /** The last refused page handshake: version skew, token, port or protocol, in `reason`. */ export interface LinkHelloFailure { reason: string; at: number; sdkVersion?: string; } /** A `.reticle` folder with runs that never reached the platform. `root` is `~`-relative. */ export interface LinkUnsyncedRoot { root: string; runs: number; linked: boolean; /** The project the folder belongs to, so a board lists only its own. Absent when none is named. */ projectId?: string; } /** * Markers a daemon adds to an app's `channels` beside the protocol channel ids, for the two * capabilities no channel names. Sent only on evidence, never while the gap that names the same * capability is recorded: absence of both reads as "not seen yet", never as covered. */ export declare const CoverageMarker: { /** The page carries `data-reticle-source` (the build plugin is active). */ readonly SOURCE: "source"; /** The app's snapshots show `data-testid` on its controls. */ readonly TESTID: "testid"; }; export type CoverageMarker = (typeof CoverageMarker)[keyof typeof CoverageMarker]; /** * The file:line capability's name (`CoverageCapability.SOURCE_MAPPING` is this). Here, beside the * markers, so a page can say it does not apply without loading the coverage rules into first load. */ export declare const SOURCE_MAPPING_CAPABILITY = "file:line source mapping";