import type { InteractionModeInfo } from '../utils/interaction-mode.js'; export type IssueSeverity = 'error' | 'warning'; export interface Issue { code: string; severity: IssueSeverity; message: string; details?: Record; remediation?: string; docsUrl?: string; } export interface SdkInfo { name: string | null; version: string | null; latest: string | null; outdated: boolean; isAuthKit: boolean; language: string; } export interface LanguageInfo { name: string; manifestFile?: string; runtimeVersion?: string; packageManager?: string; } export interface FrameworkInfo { name: string | null; version: string | null; variant?: string; expectedCallbackPath?: string; detectedPort?: number; } export interface RuntimeInfo { nodeVersion: string; packageManager: string | null; packageManagerVersion: string | null; } export interface EnvironmentInfo { apiKeyConfigured: boolean; apiKeyType: 'staging' | 'production' | null; clientId: string | null; redirectUri: string | null; cookieDomain: string | null; baseUrl: string | null; } /** Internal environment data - not included in report output */ export interface EnvironmentRaw { apiKey: string | null; clientId: string | null; baseUrl: string | null; } export interface EnvironmentCheckResult { info: EnvironmentInfo; raw: EnvironmentRaw; } export interface ConnectivityInfo { apiReachable: boolean; latencyMs: number | null; tlsValid: boolean; error?: string; } export interface HostExecutionFailure { capability: string; detail: string; operation?: string; target?: string; label?: string; } export interface HostExecutionInfo { mode: 'interactive' | 'non-interactive'; ok: boolean; failures: HostExecutionFailure[]; warning?: string; } export interface DashboardSettings { redirectUris: string[]; authMethods: string[]; sessionTimeout: string | null; mfa: 'optional' | 'required' | 'disabled' | null; organizationCount: number; } export interface RedirectUriComparison { codeUri: string | null; dashboardUris: string[]; match: boolean; source?: 'env' | 'inferred'; } export interface CredentialValidation { valid: boolean; clientIdMatch: boolean; error?: string; } export interface DashboardFetchResult { settings: DashboardSettings | null; credentialValidation?: CredentialValidation; error?: string; } export interface AuthPatternFinding { code: string; severity: IssueSeverity; message: string; filePath?: string; remediation?: string; docsUrl?: string; } export interface AuthPatternInfo { checksRun: number; findings: AuthPatternFinding[]; } export interface SkillAgentStatus { agent: string; installedVersion: string | null; stale: boolean; } export interface SkillsInfo { bundledVersion: string | null; agents: SkillAgentStatus[]; } /** * Result of `workos doctor --fix` refreshing WorkOS skills. Captured per agent * so the human-mode renderer can show a before/after line and the JSON consumer * can reason about which agents changed. */ export interface SkillsRefreshResult { /** Marker version per agent.name BEFORE refresh (null = no marker). */ before: Record; /** Marker version per agent.name AFTER refresh. */ after: Record; /** Skills the refresh was scoped to (the FIXABLE_SKILLS allowlist). */ skillsInstalled: string[]; } export interface DoctorReport { version: string; timestamp: string; interactionMode: InteractionModeInfo; project: { path: string; packageManager: string | null; }; sdk: SdkInfo; language: LanguageInfo; runtime: RuntimeInfo; framework: FrameworkInfo; environment: EnvironmentInfo; hostExecution: HostExecutionInfo; connectivity: ConnectivityInfo; dashboardSettings?: DashboardSettings; dashboardError?: string; redirectUris?: RedirectUriComparison; credentialValidation?: CredentialValidation; authPatterns?: AuthPatternInfo; aiAnalysis?: AiAnalysis; skills?: SkillsInfo; /** Present only when `--fix` actually performed a refresh. */ skillsRefresh?: SkillsRefreshResult; issues: Issue[]; summary: { errors: number; warnings: number; healthy: boolean; }; } export interface AiFinding { severity: 'error' | 'warning' | 'info'; title: string; detail: string; remediation: string; filePath?: string; } export interface AiAnalysis { findings: AiFinding[]; summary: string; model: string; durationMs: number; skipped?: boolean; skipReason?: string; } export interface DoctorOptions { installDir: string; verbose?: boolean; skipApi?: boolean; skipAi?: boolean; json?: boolean; copy?: boolean; /** When true, refresh stale WorkOS skills (constrained to workos/ + workos-widgets/). */ fix?: boolean; }