types.ts
1 export type SlideType = 'foundation' | 'feature' | 'refactor' | 'bugfix' | 'test' | 'config' | 'docs'; 2 3 export interface CiCheck { 4 name: string; 5 status: 'queued' | 'in_progress' | 'completed'; 6 conclusion: string | null; 7 } 8 9 export interface ReviewSummary { 10 approved: number; 11 changesRequested: number; 12 commented: number; 13 } 14 15 export interface DiffHunk { 16 filePath: string; 17 hunkHeader: string; 18 content: string; 19 language: string; 20 renderedHtml: string; 21 } 22 23 export interface ReviewCheck { 24 text: string; 25 filePath?: string; 26 startLine?: number; 27 } 28 29 export interface Slide { 30 id: string; 31 slideNumber: number; 32 title: string; 33 slideType: SlideType; 34 narrative: string; 35 reviewFocus: string | null; 36 diffHunks: DiffHunk[]; 37 contextSnippets: string[]; 38 affectedFiles: string[]; 39 dependsOn: string[]; 40 mermaidDiagram?: string | null; 41 reviewChecks?: ReviewCheck[]; 42 } 43 44 // Intermediate types for raw AI response (before hunk resolution) 45 export interface AISlide { 46 id: string; 47 slideNumber: number; 48 title: string; 49 slideType: SlideType; 50 narrative: string; 51 reviewFocus: string | null; 52 diffHunkIds: string[]; 53 contextSnippets: string[]; 54 affectedFiles: string[]; 55 dependsOn: string[]; 56 mermaidDiagram?: string | null; 57 reviewChecks?: ReviewCheck[]; 58 } 59 60 export interface WebSource { 61 url: string; 62 title: string; 63 } 64 65 export interface AIReviewGuide { 66 prTitle: string; 67 prDescription: string; 68 prUrl: string; 69 author: string; 70 summary: string; 71 riskLevel: 'low' | 'medium' | 'high'; 72 riskRationale: string; 73 totalFilesChanged: number; 74 totalLinesChanged: number; 75 slides: AISlide[]; 76 webSources?: WebSource[]; 77 } 78 79 export interface ReviewGuide { 80 prTitle: string; 81 prDescription: string; 82 prUrl: string; 83 author: string; 84 summary: string; 85 riskLevel: 'low' | 'medium' | 'high'; 86 riskRationale: string; 87 totalFilesChanged: number; 88 totalLinesChanged: number; 89 neighborFileCount?: number; 90 excludedFiles?: string[]; 91 generationDurationMs?: number; 92 slides: Slide[]; 93 headSha?: string; 94 webSources?: WebSource[]; 95 } 96 97 export interface PrStatus { 98 labels: string[]; 99 mergeable: boolean | null; 100 isDraft: boolean; 101 ciChecks: CiCheck[]; 102 ciConclusion: 'success' | 'failure' | 'pending' | 'neutral'; 103 reviewSummary: ReviewSummary; 104 baseBranch: string; 105 commitCount: number; 106 requestedReviewers: string[]; 107 requestedTeams: string[]; 108 mergeableState: string | null; 109 autoMerge: { method: string } | null; 110 milestone: { title: string; dueOn: string | null } | null; 111 } 112 113 export type DiffSide = 'LEFT' | 'RIGHT'; 114 export type ReviewEvent = 'APPROVE' | 'REQUEST_CHANGES' | 'COMMENT'; 115 116 export interface PendingReviewComment { 117 id: string; 118 filePath: string; 119 line: number; 120 side: DiffSide; 121 body: string; 122 hunkHeader: string; 123 codeSnippet: string; 124 slideIndex: number; 125 } 126 127 export interface SubmitReviewRequest { 128 prUrl: string; 129 headSha: string; 130 event: ReviewEvent; 131 body: string; 132 comments: { path: string; line: number; side: DiffSide; body: string }[]; 133 } 134 135 export interface ReviewHistoryEntry { 136 id: string; 137 prTitle: string; 138 prUrl: string; 139 author: string; 140 riskLevel: 'low' | 'medium' | 'high'; 141 status?: 'generating' | 'completed' | 'failed'; // undefined defaults to 'completed' (backward compat) 142 error?: string; 143 model?: ModelId; 144 generationDurationMs?: number; 145 savedAt: string; // ISO date string 146 unread?: boolean; 147 prState?: 'open' | 'merged' | 'closed'; 148 prHeadSha?: string; 149 } 150 151 export interface StartReviewResult { 152 reviewId: string; 153 prTitle: string; 154 prUrl: string; 155 author: string; 156 } 157 158 export type Provider = 'claude' | 'gemini'; 159 160 export type ClaudeModel = 'claude-opus-4-6' | 'claude-sonnet-4-6' | 'claude-haiku-4-5-20251001'; 161 162 export type GeminiModel = 163 | 'gemini-3.1-pro-preview' 164 | 'gemini-3-pro-preview' 165 | 'gemini-3-flash-preview' 166 | 'gemini-2.5-pro' 167 | 'gemini-2.5-flash'; 168 169 export type ModelId = ClaudeModel | GeminiModel; 170 171 export interface Preferences { 172 instructions: string; 173 provider: Provider; 174 model: ModelId; 175 thinking: boolean; 176 signalBoost: boolean; 177 smartImports: boolean; 178 reviewSuggestions: boolean; 179 enableTools: boolean; 180 enableWebResearch: boolean; 181 autoReviewOnRequest: boolean; 182 codeTheme: string; 183 codeFont: string; 184 claudePath: string; 185 geminiPath: string; 186 notifications: boolean; 187 diffLayout: 'unified' | 'split'; 188 includeAllFiles: boolean; 189 reviewSignature: boolean; 190 } 191 192 export interface SendSlideChatRequest { 193 prTitle: string; 194 prDescription: string; 195 summary: string; 196 slideTitle: string; 197 slideNarrative: string; 198 slideReviewFocus: string | null; 199 affectedFiles: string[]; 200 diffContent: string; 201 history: Array<{ role: 'user' | 'assistant'; content: string }>; 202 question: string; 203 provider: Provider; 204 model: ModelId; 205 } 206 207 export interface GenerateReviewRequest { 208 prUrl: string; 209 provider: Provider; 210 model: ModelId; 211 instructions?: string; 212 thinking?: boolean; 213 signalBoost?: boolean; 214 smartImports?: boolean; 215 reviewSuggestions?: boolean; 216 webResearch?: boolean; 217 excludedFiles?: string[]; 218 } 219 220 export interface GenerateReviewResponse { 221 review: ReviewGuide; 222 } 223 224 export interface ChangedFile { 225 filename: string; 226 status: 'added' | 'modified' | 'deleted' | 'renamed'; 227 additions: number; 228 deletions: number; 229 previous_filename?: string; 230 } 231 232 export interface FreshnessCommit { 233 sha: string; 234 message: string; 235 authorLogin: string; 236 authorDate: string; 237 } 238 239 export type FreshnessResult = 240 | { status: 'current' } 241 | { status: 'stale'; aheadBy: number; commits: FreshnessCommit[] } 242 | { status: 'force-pushed' } 243 | { status: 'unknown'; reason: string }; 244 245 export interface PrSearchResult { 246 number: number; 247 title: string; 248 url: string; 249 repoOwner: string; 250 repoName: string; 251 author: string; 252 updatedAt: string; 253 isDraft: boolean; 254 role: 'author' | 'review-requested'; 255 } 256 257 export interface UpdateInfo { 258 version: string; 259 releaseUrl: string; 260 } 261 262 export interface PrMetadata { 263 title: string; 264 description: string; 265 author: string; 266 baseBranch: string; 267 headBranch: string; 268 headSha: string; 269 merged: boolean; 270 state: 'open' | 'closed'; 271 createdAt: string; 272 updatedAt: string; 273 url: string; 274 labels: string[]; 275 mergeable: boolean | null; 276 isDraft: boolean; 277 commitCount: number; 278 requestedReviewers: string[]; 279 requestedTeams: string[]; 280 mergeableState: string | null; 281 autoMerge: { method: string } | null; 282 milestone: { title: string; dueOn: string | null } | null; 283 }