/** * Session lifecycle, health, control, and lease constants. Re-exported from the package index. */ /** * Live-control: per-session lifecycle state (server-owned). The presenter panel mirrors it. * `active → paused → active … → ended`; `ended` is terminal. */ export declare const SessionState: { readonly ACTIVE: "active"; readonly PAUSED: "paused"; readonly ENDED: "ended"; }; export type SessionState = (typeof SessionState)[keyof typeof SessionState]; /** Narrow an unknown wire value to a SessionState (no zod needed at this membership boundary). */ export declare function isSessionState(value: unknown): value is SessionState; /** * Sentinel session label meaning "give this tab its own unique id". The SDK maps it (and an absent * label) to a per-tab id so several tabs — a human tab + an Reticle-driven tour, a Director-cut popup — * never collide on one session id. Pass an explicit label only when tabs should intentionally share. */ export declare const SESSION_AUTO = "auto"; /** Live-control: kinds a human can emit from the panel (the `kind` of a HUMAN_CONTROL event). */ export declare const HumanControlKind: { readonly PAUSE: "pause"; readonly RESUME: "resume"; readonly END: "end"; readonly MESSAGE: "message"; /** Human clicked ▶ on a saved flow in the panel — replay it (no agent). `text` carries the name. */ readonly REPLAY: "replay"; /** * Human asked the panel to push to the dashboard NOW, rather than waiting for the sync timer. * * The timer already keeps the dashboard current on its own, so this is not how sync happens — it * is how somebody watching the panel stops wondering whether it is happening. Carries nothing: * what to send is the daemon's question, and a panel that named artifacts could disagree with it. */ readonly SYNC: "sync"; }; export type HumanControlKind = (typeof HumanControlKind)[keyof typeof HumanControlKind]; /** * Human review marks: the durability tier of the anchor that pins a mark to an element. Mirrors the * browser's auto-anchor AnchorStrategy values (testid > component@source > role > position) so the * agent draining a mark knows how trustworthy the element address is. Wire-owned here because the * mark crosses browser → bridge → agent; the browser maps its synthesized anchor onto these. */ export declare const MarkAnchorStrategy: { readonly TESTID: "testid"; readonly COMPONENT: "component"; readonly ROLE: "role"; readonly POSITION: "position"; }; export type MarkAnchorStrategy = (typeof MarkAnchorStrategy)[keyof typeof MarkAnchorStrategy]; /** Human review marks: lifecycle of a mark in the server-side review store. */ export declare const MarkStatus: { /** Flagged by the human, not yet addressed by the agent. */ readonly PENDING: "pending"; /** The agent claimed the mark as fixed (reticle_review resolve). Terminal. */ readonly RESOLVED: "resolved"; }; export type MarkStatus = (typeof MarkStatus)[keyof typeof MarkStatus]; /** * SDK page-health heartbeat cadence (native timer) and the server's * throttle threshold. Kept named so the server's staleness check can be reasoned about * against the SDK's heartbeat (≈ 2 missed heartbeats ⇒ throttled). */ export declare const SESSION_HEALTH: { readonly HEARTBEAT_MS: 5000; /** lastSeenMs beyond this ⇒ throttled (≈ 2 missed heartbeats). */ readonly STALE_THRESHOLD_MS: 12000; }; /** * Server-authoritative session liveness. The browser-side idle timer is throttled in a backgrounded * tab and dies entirely if the agent (MCP client) kills the bridge — so the Node server (immune to * throttling) owns the decision: a session whose AGENT has been idle past `IDLE_END_MS` is reaped and * ended via a PRESENTER push (which a throttled tab still receives). `BRIDGE_LOST_MS` is the browser's * own fallback: when it cannot reach the bridge for this long (server/agent process gone), it ends the * session itself so the HUD never sits "running" forever. */ export declare const SESSION_LIFECYCLE: { /** * Default agent-idle window before the panel hands back to the human as WAITING. The agent signals * this IMMEDIATELY via reticle_session {action:"yield"}; this reaper is only the slow backstop for a forgotten yield, so * it's deliberately long (a short window would auto-end a session mid slow-step). reticle_session-tunable. */ readonly IDLE_END_MS: 300000; /** Floor for a tuned idle window (so an agent can't disable the safety net). */ readonly IDLE_END_MIN_MS: 5000; /** How often the server reaper sweeps sessions for idle/disconnected ones. */ readonly REAP_INTERVAL_MS: 5000; /** Browser fallback: continuous failure to reach the bridge for this long ⇒ self-end the session. */ readonly BRIDGE_LOST_MS: 15000; /** * Daemon self-shutdown: after this long with NO agent connected, NO browser session, and NO pool * lease, the detached daemon tears itself down (closes Chromium + bridge, frees the port, removes its * pidfile, exits) so Reticle never lingers eating resources after the editor closes. Long enough to * survive brief agent reconnects between turns; overridable via RETICLE_IDLE_SHUTDOWN_MS (0 = never). */ readonly DAEMON_IDLE_SHUTDOWN_MS: 300000; /** How often the daemon checks whether it has gone idle. Unref'd, so it never keeps the process up. */ readonly DAEMON_IDLE_CHECK_MS: 30000; }; /** * Coding-agent session hygiene thresholds. Coding agents (Claude Code, Codex, Cursor) often * complete their task and close their context without calling reticle_session {action:"end"}. These constants * drive two passive reminder layers: a one-time session_lease on first call, and recurring * session_age_warning fields after WARN_AFTER_MS. */ export declare const SESSION_LEASE: { /** ms after which age warnings appear on every session-bound tool result. */ readonly WARN_AFTER_MS: 600000; /** ms after which reticle_sessions marks a session as stale. */ readonly STALE_AFTER_MS: 1800000; }; /** Why the SDK emitted a PAGE_HEALTH event. */ export declare const HealthReason: { readonly VISIBILITY: "visibilitychange"; readonly FOCUS: "focus"; readonly BLUR: "blur"; readonly HEARTBEAT: "heartbeat"; readonly INITIAL: "initial"; }; export type HealthReason = (typeof HealthReason)[keyof typeof HealthReason]; /** * The one thing to DO when nothing is connected — the executable half of the no-session diagnosis. * * The prose diagnosis tells the cases apart well, and an agent still has to translate it into a * command. This is that command's kind, so the agent branches on a value instead of on a sentence. * Wire-owned because it crosses daemon → agent on `reticle_sessions`. */ export declare const NoSessionAction: { /** Nothing is listening anywhere: the app is not running. Carries the project's own dev script. */ readonly START_DEV_SERVER: "start_dev_server"; /** Something is listening but this project carries no Reticle SDK — wire it first. */ readonly RUN_INIT: "run_init"; /** A wired app is up and no page is loaded — Reticle only ever sees a page a browser has opened. */ readonly OPEN_APP: "open_app"; /** A session was here and went away: reopen the tab, or take a lease. */ readonly REOPEN_APP: "reopen_app"; /** * The app IS connected — to another daemon on this machine. Nothing to open, nothing to install. * * Its own kind because every other action here is wrong for it: the app is running, wired and * live, so `open_app`, `run_init` and `start_dev_server` all send the agent to fix something that * is not broken, and `reopen_app` points it at a tab that is already open. */ readonly DAEMON_SPLIT: "daemon_split"; }; export type NoSessionAction = (typeof NoSessionAction)[keyof typeof NoSessionAction];