import { z } from 'zod'; /** * Producer health — the "is anybody actually watching?" half of every check * resource (`typecheck://current`, `lint://current`, `build://current`). * * WHY this exists, concretely: `typecheck://current` shipped as * `{"status":"unknown","errorCount":0,"revision":0}` and `lint://current` as * `{"status":"unknown","errorCount":0,"warningCount":0,"revision":0}` — and an * agent reading either one cannot tell those apart from a healthy, silent, * genuinely-clean system. They were not clean. `startTscCollector` and * `runEslintOnce` existed, were exported from `@lensmcp/session`, and were * called by NOTHING; the dev cluster's real type checking (the tsgo plugin) * printed diagnostics to the console and to no bus at all. So those resources * had never received a single event in their lives, and said so in a way that * read exactly like "all good". * * `revision: 0` was the only tell, and it is far too subtle to be a contract: * one empty read teaches a reader to stop asking, which is precisely what * happened. So every check resource now states, in the body, whether a * producer has EVER reported (`producer`), which producers are live * (`producers`), how old the newest report is (`ageMs`/`stale`), and a * sentence a human or an agent can act on (`detail`). * * `status` keeps its original value set (`unknown | clean | …`) so existing * readers — the MCP resource wrappers and the human dashboard — are unaffected; * everything here is additive. */ /** * Has any producer ever reported into this resource? * * - `none` — no producer has ever reported. `status` is NOT evidence of * health; nothing is watching. This is the state the three * check resources were silently stuck in. * - `connected` — at least one producer has reported at least once, so * `status` reflects a real run. * * Deliberately NOT a third `stale` member: staleness is orthogonal (a * connected producer that has not re-run recently is still connected), and * folding it in here would force readers to re-derive "did anyone ever * report?" from a union. Read `stale`/`ageMs` for freshness. */ export declare const ProducerStateSchema: z.ZodEnum<{ none: "none"; connected: "connected"; }>; export type ProducerState = z.infer; /** Outcome of a producer's most recent run. */ export declare const ProducerRunStatusSchema: z.ZodEnum<{ error: "error"; running: "running"; clean: "clean"; failing: "failing"; }>; export type ProducerRunStatus = z.infer; /** * One reporting producer. Keyed by `id` so a multi-service cluster (13 pods, * each running its own tsgo check against its own tsconfig, all appending to * ONE `.lensmcp/events.jsonl`) shows up as 13 rows rather than a single * last-writer-wins verdict. */ export declare const ProducerReportSchema: z.ZodObject<{ id: z.ZodString; tool: z.ZodString; project: z.ZodOptional; firstReportedAt: z.ZodNumber; lastReportedAt: z.ZodNumber; lastRunStatus: z.ZodEnum<{ error: "error"; running: "running"; clean: "clean"; failing: "failing"; }>; lastRunDurationMs: z.ZodOptional; errorCount: z.ZodNumber; warningCount: z.ZodOptional; error: z.ZodOptional; }, z.core.$strip>; export type ProducerReport = z.infer; /** * The additive block every check resource carries. Mixed into * `typecheck://current`, `lint://current` and `build://current`. */ export declare const ProducerHealthSchema: z.ZodObject<{ producer: z.ZodEnum<{ none: "none"; connected: "connected"; }>; producers: z.ZodArray; firstReportedAt: z.ZodNumber; lastReportedAt: z.ZodNumber; lastRunStatus: z.ZodEnum<{ error: "error"; running: "running"; clean: "clean"; failing: "failing"; }>; lastRunDurationMs: z.ZodOptional; errorCount: z.ZodNumber; warningCount: z.ZodOptional; error: z.ZodOptional; }, z.core.$strip>>; lastReportedAt: z.ZodOptional; ageMs: z.ZodOptional; stale: z.ZodBoolean; detail: z.ZodString; }, z.core.$strip>; export type ProducerHealth = z.infer; /** * A connected producer whose newest report is older than this is reported * `stale`. Generous on purpose: these producers are edge-triggered (they run * on rebuild / on demand), so silence is normal and is NOT evidence of a * problem — it only means the verdict may predate the current source. */ export declare const PRODUCER_STALE_AFTER_MS: number; /** * Fold a producer registry into the {@link ProducerHealth} block. * * Lives here rather than in each reducer so `typecheck`, `lint` and `build` * cannot drift into three different definitions of "nobody is watching" — the * exact class of divergence that let the original bug hide in two of the three. * * `now` is injected so the value is testable and so callers can pin one clock * across a single resource render. */ export declare function summariseProducers(args: { producers: readonly ProducerReport[]; /** Domain label used in `detail`, e.g. `typecheck`. */ domain: string; /** Appended to `detail` when there is no producer — how to get one. */ noProducerHint: string; now?: number; }): ProducerHealth;