@@ -5,6 +5,13 @@ import {
55 getPullRequestComments ,
66 createReviewComment ,
77 replyToComment ,
8+ getReviews ,
9+ createReview ,
10+ getCheckRuns ,
11+ getCombinedStatus ,
12+ mergePullRequest ,
13+ getIssueComments ,
14+ createIssueComment ,
815} from "./github" ;
916import { parseDiffWithHighlighting } from "./diff" ;
1017
@@ -105,6 +112,13 @@ api.post("/parse-diff", async (c) => {
105112 try {
106113 // Use SHA as cache key for immutable caching
107114 const parsed = parseDiffWithHighlighting ( patch , filename , previousFilename , sha ) ;
115+
116+ // Set cache headers for immutable content (SHA-based)
117+ if ( sha ) {
118+ c . header ( "Cache-Control" , "public, max-age=31536000, immutable" ) ;
119+ c . header ( "ETag" , `"${ sha } "` ) ;
120+ }
121+
108122 return c . json ( parsed ) ;
109123 } catch ( error ) {
110124 return c . json (
@@ -114,4 +128,131 @@ api.post("/parse-diff", async (c) => {
114128 }
115129} ) ;
116130
131+ // ============================================================================
132+ // Review APIs
133+ // ============================================================================
134+
135+ // Get PR reviews
136+ api . get ( "/pr/:owner/:repo/:number/reviews" , async ( c ) => {
137+ const { owner, repo, number } = c . req . param ( ) ;
138+ try {
139+ const reviews = await getReviews ( owner , repo , parseInt ( number , 10 ) ) ;
140+ return c . json ( reviews ) ;
141+ } catch ( error ) {
142+ return c . json (
143+ { error : error instanceof Error ? error . message : "Failed to fetch reviews" } ,
144+ 500
145+ ) ;
146+ }
147+ } ) ;
148+
149+ // Submit a review
150+ api . post ( "/pr/:owner/:repo/:number/reviews" , async ( c ) => {
151+ const { owner, repo, number } = c . req . param ( ) ;
152+ const body = await c . req . json ( ) ;
153+
154+ try {
155+ const review = await createReview (
156+ owner ,
157+ repo ,
158+ parseInt ( number , 10 ) ,
159+ body . commit_id ,
160+ body . event ,
161+ body . body || "" ,
162+ body . comments || [ ]
163+ ) ;
164+ return c . json ( review ) ;
165+ } catch ( error ) {
166+ return c . json (
167+ { error : error instanceof Error ? error . message : "Failed to submit review" } ,
168+ 500
169+ ) ;
170+ }
171+ } ) ;
172+
173+ // ============================================================================
174+ // Checks & Status
175+ // ============================================================================
176+
177+ // Get check runs
178+ api . get ( "/pr/:owner/:repo/:number/checks" , async ( c ) => {
179+ const { owner, repo, number } = c . req . param ( ) ;
180+ try {
181+ const pr = await getPullRequest ( owner , repo , parseInt ( number , 10 ) ) ;
182+ const [ checkRuns , status ] = await Promise . all ( [
183+ getCheckRuns ( owner , repo , pr . head . sha ) ,
184+ getCombinedStatus ( owner , repo , pr . head . sha ) ,
185+ ] ) ;
186+ return c . json ( { checkRuns : checkRuns . check_runs , status } ) ;
187+ } catch ( error ) {
188+ return c . json (
189+ { error : error instanceof Error ? error . message : "Failed to fetch checks" } ,
190+ 500
191+ ) ;
192+ }
193+ } ) ;
194+
195+ // ============================================================================
196+ // Merge
197+ // ============================================================================
198+
199+ api . post ( "/pr/:owner/:repo/:number/merge" , async ( c ) => {
200+ const { owner, repo, number } = c . req . param ( ) ;
201+ const body = await c . req . json ( ) ;
202+
203+ try {
204+ const result = await mergePullRequest (
205+ owner ,
206+ repo ,
207+ parseInt ( number , 10 ) ,
208+ body . merge_method || "squash" ,
209+ body . commit_title ,
210+ body . commit_message
211+ ) ;
212+ return c . json ( result ) ;
213+ } catch ( error ) {
214+ return c . json (
215+ { error : error instanceof Error ? error . message : "Failed to merge PR" } ,
216+ 500
217+ ) ;
218+ }
219+ } ) ;
220+
221+ // ============================================================================
222+ // Issue Comments (PR conversation)
223+ // ============================================================================
224+
225+ api . get ( "/pr/:owner/:repo/:number/conversation" , async ( c ) => {
226+ const { owner, repo, number } = c . req . param ( ) ;
227+ try {
228+ const comments = await getIssueComments ( owner , repo , parseInt ( number , 10 ) ) ;
229+ return c . json ( comments ) ;
230+ } catch ( error ) {
231+ return c . json (
232+ { error : error instanceof Error ? error . message : "Failed to fetch conversation" } ,
233+ 500
234+ ) ;
235+ }
236+ } ) ;
237+
238+ api . post ( "/pr/:owner/:repo/:number/conversation" , async ( c ) => {
239+ const { owner, repo, number } = c . req . param ( ) ;
240+ const body = await c . req . json ( ) ;
241+
242+ try {
243+ const comment = await createIssueComment (
244+ owner ,
245+ repo ,
246+ parseInt ( number , 10 ) ,
247+ body . body
248+ ) ;
249+ return c . json ( comment ) ;
250+ } catch ( error ) {
251+ return c . json (
252+ { error : error instanceof Error ? error . message : "Failed to add comment" } ,
253+ 500
254+ ) ;
255+ }
256+ } ) ;
257+
117258export default api ;
0 commit comments