/** * Browser half of the panel's data channel: TWO one-shot reads on the host's * shared `/api` typert gateway. * * - `readDigest(...)` — the session digest (`enforcement`, `knowledge`, * `selection`, plus the delivery fallback member). It replaces the retired * 5-second poll: the panel reads it when it mounts and after an explicit * action, and nothing here schedules anything. * - `readView(...)` — one engine `DashboardView` (plan dsh-panel-unification * Task 4a). A screen reads its own view; the dashboard and this host see the * same DTOs. * * NO STATE, NO TIMER, NO SUBSCRIPTION: this class is an RPC face, not a store. * Keeping the reads app-local means two screens reading different views cannot * overwrite each other, and a collapsed or unmounted seat costs nothing. * * Every failure mode is an explicit kind (`no-harness`, `unavailable` with a * reason); nothing here throws, and an unreadable answer is never a half-parsed * payload. * * @module @mstar-harness/dsh/client/panel/panel-snapshot-client */ import type { ConnectionRpcResult } from '@deepseek-ai/dsh-client-connection/client'; import type { PanelSnapshotRead } from '../../panel/panel-snapshot.ts'; import type { DashboardViewRead } from '../../panel/panel-snapshot-endpoint.ts'; import { DASHBOARD_VIEW_ENDPOINT, PANEL_SNAPSHOT_ENDPOINT } from '../../engine-status-wire.ts'; export { DASHBOARD_VIEW_ENDPOINT, PANEL_SNAPSHOT_ENDPOINT }; /** * Structural face of the client `connection` service the panel needs — the * generic RPC caller of the shared gateway. Declared structurally (not * imported as a value) so the bundle stays free of a runtime dependency on the * transport package. */ export interface MstarPanelSnapshotConnection { readonly rpc: { call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise>; }; } /** The digest read's target: what the host needs to resolve the `{HARNESS_DIR}`. */ export interface PanelSnapshotTarget { readonly sessionId: string; readonly cwd: string; readonly workflowId?: string; readonly iterationId?: string; readonly projectId?: string; } /** * Per-request deadline. A wedged gateway must not leave a read pending forever: * the request is aborted at this bound and the caller gets an explicit * `unavailable` reason. This is the ONLY timer in the read path — it bounds one * request and schedules no follow-up (no poll, no retry). */ export declare const PANEL_READ_DEADLINE_MS = 5000; /** * Validate one digest answer into the closed {@link PanelSnapshotRead} union. * Total: an unreadable answer degrades to `unavailable`, never a half-parsed * payload. */ export declare function parsePanelSnapshotRead(value: unknown): PanelSnapshotRead; /** * Validate one per-view answer into the closed {@link DashboardViewRead} union. * The envelope is passed through as the engine produced it; only the two * non-answers are decoded here. */ export declare function parseDashboardViewRead(value: unknown): DashboardViewRead; /** The panel's transport client: two one-shot reads, no scheduling, no state. */ export declare class MstarPanelSnapshotClient { private readonly connection; constructor(connection: MstarPanelSnapshotConnection | undefined); /** * Read the session digest once. * @param target - the asserted session/workspace (ids are server-resolved). * @returns the digest, `no-harness`, or an explicit reason. */ readDigest(target: PanelSnapshotTarget): Promise; /** * Read ONE engine dashboard view — the per-view path. * * ONE request per call and NOTHING else: no state write, no subscription, no * visibility gate, and NO TIMER of any kind. Every failure mode is an explicit * kind, never a throw. * @param input - the session/workspace assertion plus the view identity. * @returns the engine envelope, `no-harness`, or an explicit reason. */ readView(input: { sessionId: string; cwd: string; view: string; params?: Record; id?: string; }): Promise; }