import type { AppQualityIssue, AppQualitySeverity } from "../app-quality/engine.js"; export type UxTenetId = "clarity" | "feedback" | "control" | "consistency" | "accessibility" | "error-recovery" | "progressive-disclosure" | "workflow-fit" | "trust" | "state-continuity"; export type UxTrapId = "ambiguous-affordance" | "missing-state" | "silent-system" | "choice-overload" | "layout-instability" | "token-drift" | "inaccessible-interaction" | "copy-theater" | "context-leak" | "destructive-default"; export interface UxTenetDefinition { id: UxTenetId; name: string; description: string; protectBy: string[]; } export interface UxTrapDefinition { id: UxTrapId; name: string; description: string; defaultFix: string; tenetIds: UxTenetId[]; } export type UxFindingSource = "app-quality" | "screenshot" | "manual" | "mcp"; /** * How a finding was evidenced. 2.3 only ever emits "static-scan" — the other * values are reserved so 2.4's rendered probes / vision critique can slot in * without another schema bump. */ export type UxFindingProvenance = "static-scan" | "rendered-probe" | "vision" | "manual"; export interface UxAuditFinding { id: string; title: string; severity: AppQualitySeverity; tenetIds: UxTenetId[]; trapIds: UxTrapId[]; evidence: string[]; recommendation: string; source: UxFindingSource; provenance: UxFindingProvenance; artifactPath?: string; confidence?: number; affectedFiles?: string[]; } export interface UxTenetCoverage { tenetId: UxTenetId; name: string; /** * "not-assessed" means no static-scan evidence path can ever evidence this * tenet — it is NOT the same as "protected". Only tenets the scan can * actually violate may read "protected" when clean. */ status: "protected" | "at-risk" | "unknown" | "not-assessed"; findingIds: string[]; notes: string[]; } export interface UxTrapRisk { trapId: UxTrapId; name: string; /** "not-assessed" — no static-scan evidence path exists for this trap; see UxTenetCoverage.status. */ status: "clear" | "watch" | "present" | "not-assessed"; riskScore: number; findingIds: string[]; defaultFix: string; note?: string; } export interface UxAuditReport { schemaVersion: 2; target: string; generatedAt: string; score: number; tenetCoverage: UxTenetCoverage[]; trapRisks: UxTrapRisk[]; findings: UxAuditFinding[]; recommendedTweaks: string[]; artifactPath?: string; /** Present when a screenshot was attached: it is recorded, not analyzed — no vision pass runs in 2.3. */ artifactNote?: string; metadata?: { issueCount?: number; appQualityScore?: number; }; } export interface BuildUxAuditReportInput { target?: string; generatedAt?: string; artifactPath?: string | null; issues?: AppQualityIssue[]; appQualityScore?: number; source?: UxFindingSource; } export declare const UX_TENETS: UxTenetDefinition[]; export declare const UX_TRAPS: UxTrapDefinition[]; export declare function mapAppQualityIssueToUxFinding(issue: AppQualityIssue): UxAuditFinding; export declare function buildUxAuditReport(input: BuildUxAuditReportInput): UxAuditReport; export declare function writeUxAuditReport(projectRoot: string, report: UxAuditReport): Promise<{ jsonPath: string; markdownPath: string; }>; export declare function renderUxAuditMarkdown(report: UxAuditReport): string;