/** * The FEEDBACK and IDENTITY contract — the only two things Reticle ever sends that a person wrote. * * They are a different privacy class from the rest of telemetry, which is counters and enums that * cannot describe anyone: these two carry authored text and a self-declared identity, they are never * emitted passively, and they each have their own consent story. Keeping them in one file makes that * boundary something you can see rather than something you have to remember. * * Neither is ever populated by inference. A `Feedback` exists because an agent called * `reticle_feedback` or a human ran `reticle feedback`; an `Identity` exists because a human ran * `reticle identify`. There is no code path to either that a person did not start. */ import { z } from 'zod'; /** Who authored the feedback. Agents report failures; humans also rate the experience. */ export declare const FeedbackSource: { readonly AGENT: "agent"; readonly HUMAN: "human"; }; export type FeedbackSource = (typeof FeedbackSource)[keyof typeof FeedbackSource]; /** * What kind of report this is. The first three are the agent's vocabulary — they name the three ways * Reticle fails an agent, and keeping them distinct is the whole point: a BUG is a Reticle defect, a * GAP is something Reticle cannot see at all, and an AMBIGUITY is a verdict the agent could not act * on. Lumping them into "it didn't work" destroys the only signal that says what to build next. */ export declare const FeedbackKind: { /** A tool misbehaved: wrong result, crash, or a contract it did not honor. */ readonly BUG: "bug"; /** Reticle could not observe something the agent needed — a blind spot, not a defect. */ readonly GAP: "gap"; /** The verification ran but its verdict was not decidable — pass/fail could not be told apart. */ readonly AMBIGUITY: "ambiguity"; /** * "I wish Reticle could do X." Something that does not exist and would have helped. * * Reticle is built FOR agents, so the agent is the user whose wishes matter most — and it is the * one user who never gets asked. It hits a limitation, works around it, finishes the task, and the * wish evaporates with the context window. This is the channel for it, and it is deliberately as * easy to file as a bug: the friction that stops people reporting failures stops them twice as * hard for something that is merely a nice-to-have. */ readonly FEATURE_REQUEST: "feature_request"; /** * Something that EXISTS but is awkward — too many calls, a confusing shape, a slow path. * * Kept separate from a feature request because the responses differ completely: one is "build the * missing thing", the other is "the thing is there and the ergonomics are wrong". Collapsing them * would hide the second inside the first, and the second is usually cheaper and higher-impact. */ readonly IMPROVEMENT: "improvement"; /** * "This worked, and here is what it did." An overall take on using Reticle, carrying `rating`. * * Filed by a human at a terminal OR by an agent mid-task, and the agent case is the one that was * missing: every other kind an agent can file is a complaint, so the corpus could only ever grow * into a defect list, which never says which parts are worth protecting through a change — the * question a refactor actually needs answered. * * A score alone is close to worthless here and the tool says so: a model asked for a number will * produce an agreeable one, and an agreeable number is indistinguishable from an earned one once * both are in the same column. What makes a report usable is the `text` naming the concrete * moment, which is also the only part that can be quoted or acted on. */ readonly EXPERIENCE: "experience"; }; export type FeedbackKind = (typeof FeedbackKind)[keyof typeof FeedbackKind]; /** Which shell the verified app runs in. Mirrors the SDK's own `PAGE_HEALTH` runtime report. */ export declare const AppRuntime: { readonly WEB: "web"; readonly ELECTRON: "electron"; readonly TAURI: "tauri"; }; export type AppRuntime = (typeof AppRuntime)[keyof typeof AppRuntime]; /** The rendering engine behind the connected page — coarse on purpose (three values, not a UA string). */ export declare const BrowserEngine: { readonly BLINK: "blink"; readonly GECKO: "gecko"; readonly WEBKIT: "webkit"; }; export type BrowserEngine = (typeof BrowserEngine)[keyof typeof BrowserEngine]; /** * The browser BRAND behind the connected page — the axis `engine` cannot answer. * * Chrome, Edge, Arc, Dia, Brave and Opera are all `blink`, and the most common mode by far is * `attached`: Reticle launched nothing, so the page itself is the only thing that knows which * browser it is. A CLOSED list on purpose — the raw UA string and a raw `userAgentData` brand are * both unbounded and fingerprintable, so anything unrecognised reports `OTHER` rather than * forwarding an unrecognised name. */ export declare const BrowserBrand: { readonly CHROME: "chrome"; readonly EDGE: "edge"; readonly ARC: "arc"; readonly DIA: "dia"; readonly BRAVE: "brave"; readonly OPERA: "opera"; readonly FIREFOX: "firefox"; readonly SAFARI: "safari"; /** Anything we do not recognise — including a Chromium that names no brand at all. */ readonly OTHER: "other"; }; export type BrowserBrand = (typeof BrowserBrand)[keyof typeof BrowserBrand]; /** How Reticle reaches the page: a driven CDP browser, or the SDK inside the human's own browser. */ export declare const PageDriver: { readonly CDP: "cdp"; readonly SDK: "sdk"; }; export type PageDriver = (typeof PageDriver)[keyof typeof PageDriver]; /** Where the MCP server is registered — a user-level install serves every project, a project-level one doesn't. */ export declare const McpScope: { readonly USER: "user"; readonly PROJECT: "project"; }; export type McpScope = (typeof McpScope)[keyof typeof McpScope]; export declare const FEEDBACK_TEXT_MAX = 4000; export declare const FEEDBACK_TRACE_MAX = 8000; export declare const FEEDBACK_RATING_MIN = 1; export declare const FEEDBACK_RATING_MAX = 5; /** Cap for the structured why/impact/workaround fields — prose, but bounded prose. */ export declare const FEEDBACK_FIELD_MAX = 1000; /** * The feedback body. Everything here is either author-written (`text`, `trace`, `rating`) or * environment context detected locally (`stack`, `runtime`, `engine`, …) — the context is what turns * "a tool broke" into "a tool breaks on Tauri + SvelteKit", which is the difference between a * complaint and a work item. * * `text`/`trace` are the ONLY free-text fields Reticle ever sends. They are opt-in by action (nothing * is scraped — someone typed or wrote them), capped, and redacted client-side before the wire. */ export declare const FeedbackSchema: z.ZodObject<{ source: z.ZodNativeEnum<{ readonly AGENT: "agent"; readonly HUMAN: "human"; }>; kind: z.ZodNativeEnum<{ /** A tool misbehaved: wrong result, crash, or a contract it did not honor. */ readonly BUG: "bug"; /** Reticle could not observe something the agent needed — a blind spot, not a defect. */ readonly GAP: "gap"; /** The verification ran but its verdict was not decidable — pass/fail could not be told apart. */ readonly AMBIGUITY: "ambiguity"; /** * "I wish Reticle could do X." Something that does not exist and would have helped. * * Reticle is built FOR agents, so the agent is the user whose wishes matter most — and it is the * one user who never gets asked. It hits a limitation, works around it, finishes the task, and the * wish evaporates with the context window. This is the channel for it, and it is deliberately as * easy to file as a bug: the friction that stops people reporting failures stops them twice as * hard for something that is merely a nice-to-have. */ readonly FEATURE_REQUEST: "feature_request"; /** * Something that EXISTS but is awkward — too many calls, a confusing shape, a slow path. * * Kept separate from a feature request because the responses differ completely: one is "build the * missing thing", the other is "the thing is there and the ergonomics are wrong". Collapsing them * would hide the second inside the first, and the second is usually cheaper and higher-impact. */ readonly IMPROVEMENT: "improvement"; /** * "This worked, and here is what it did." An overall take on using Reticle, carrying `rating`. * * Filed by a human at a terminal OR by an agent mid-task, and the agent case is the one that was * missing: every other kind an agent can file is a complaint, so the corpus could only ever grow * into a defect list, which never says which parts are worth protecting through a change — the * question a refactor actually needs answered. * * A score alone is close to worthless here and the tool says so: a model asked for a number will * produce an agreeable one, and an agreeable number is indistinguishable from an earned one once * both are in the same column. What makes a report usable is the `text` naming the concrete * moment, which is also the only part that can be quoted or acted on. */ readonly EXPERIENCE: "experience"; }>; /** The author's account. For an agent: what failed and why (its RCA). For a human: their words. */ text: z.ZodString; /** Agent-side only: the call/response trail that led to the failure, so the RCA is reproducible. */ trace: z.ZodOptional; /** Human-side only: 1–5. The single number that trends without reading a word. */ rating: z.ZodOptional; /** * WHY it is wanted — the goal behind the request, not the request itself. * * The most common way a feature request wastes everyone's time is arriving as a solution with the * problem stripped off. "Add a `waitForIdle` tool" is a guess about implementation; "I need to know * the page stopped changing before I assert" is a requirement, and it may already have an answer. */ need: z.ZodOptional; /** What measurably gets better — fewer calls, fewer retries, a verdict that stops being ambiguous. */ impact: z.ZodOptional; /** * How the author works around it TODAY. Usually the most valuable field in the whole report. * * A workaround is evidence rather than opinion: it shows what the agent actually did, proves the * need is real enough to have cost it something, and frequently reveals that the missing feature is * a worse fix than removing whatever forced the workaround. */ currentApproach: z.ZodOptional; /** * The MODEL the agent is running, self-reported. * * Not obtainable any other way: MCP's `clientInfo` carries a client name and version and has no * concept of a model, so the transport cannot say. The agent knows, and this report is already * something the agent authored — so asking is both the only mechanism and a reliable one. * * It matters more than it looks: a limitation that blocks a smaller model may be a docs problem * rather than a missing feature, and a request from a frontier model is evidence the surface itself * is short. Without it, every request looks the same. */ model: z.ZodOptional; /** The MCP client's own version, alongside its name — so "cursor 0.42 specifically" is answerable. */ clientVersion: z.ZodOptional; /** The framework detected in the project (`next`, `vite`, `sveltekit`, `vue`, `astro`, …). */ stack: z.ZodOptional; /** * The MAJOR version of that framework ("15", "19"). Major only, deliberately: it is what actually * segments a bug ("breaks on React 19" is a work item; "breaks on 19.0.0-rc.1-canary" is noise), * and a full version string is high-cardinality enough to start narrowing down who sent it. */ stackMajor: z.ZodOptional; runtime: z.ZodOptional>; engine: z.ZodOptional>; driver: z.ZodOptional>; /** The MCP client on the other end (`claude-code`, `cursor`, …) — self-reported at initialize. */ client: z.ZodOptional; mcpScope: z.ZodOptional>; }, "strip", z.ZodTypeAny, { text: string; kind: "bug" | "gap" | "ambiguity" | "feature_request" | "improvement" | "experience"; source: "agent" | "human"; impact?: string | undefined; trace?: string | undefined; rating?: number | undefined; need?: string | undefined; currentApproach?: string | undefined; model?: string | undefined; clientVersion?: string | undefined; stack?: string | undefined; stackMajor?: number | undefined; runtime?: "web" | "electron" | "tauri" | undefined; engine?: "blink" | "gecko" | "webkit" | undefined; driver?: "cdp" | "sdk" | undefined; client?: string | undefined; mcpScope?: "user" | "project" | undefined; }, { text: string; kind: "bug" | "gap" | "ambiguity" | "feature_request" | "improvement" | "experience"; source: "agent" | "human"; impact?: string | undefined; trace?: string | undefined; rating?: number | undefined; need?: string | undefined; currentApproach?: string | undefined; model?: string | undefined; clientVersion?: string | undefined; stack?: string | undefined; stackMajor?: number | undefined; runtime?: "web" | "electron" | "tauri" | undefined; engine?: "blink" | "gecko" | "webkit" | undefined; driver?: "cdp" | "sdk" | undefined; client?: string | undefined; mcpScope?: "user" | "project" | undefined; }>; export type Feedback = z.infer; /** What Reticle is being used for. Self-declared; never inferred. */ export declare const UsageContextKind: { readonly COMPANY: "company"; readonly SIDE_PROJECT: "side_project"; readonly OPEN_SOURCE: "open_source"; readonly LEARNING: "learning"; }; export type UsageContextKind = (typeof UsageContextKind)[keyof typeof UsageContextKind]; /** * A self-declared identity. The ONLY personal data Reticle ever transmits, and it transmits it only * because someone typed `reticle identify`. Every field is optional except the context, so a user can * say "this is a company" without saying which, or name the company without leaving an email. */ export declare const IdentitySchema: z.ZodObject<{ context: z.ZodNativeEnum<{ readonly COMPANY: "company"; readonly SIDE_PROJECT: "side_project"; readonly OPEN_SOURCE: "open_source"; readonly LEARNING: "learning"; }>; company: z.ZodOptional; email: z.ZodOptional; }, "strip", z.ZodTypeAny, { context: "company" | "side_project" | "open_source" | "learning"; company?: string | undefined; email?: string | undefined; }, { context: "company" | "side_project" | "open_source" | "learning"; company?: string | undefined; email?: string | undefined; }>; export type Identity = z.infer;