( installationId: number, owner: string, repo: string, issueNumber: number, isPullRequest: boolean )
| 136 | * Fetch full issue/PR context including all comments |
| 137 | */ |
| 138 | export async function fetchIssueContext( |
| 139 | installationId: number, |
| 140 | owner: string, |
| 141 | repo: string, |
| 142 | issueNumber: number, |
| 143 | isPullRequest: boolean |
| 144 | ): Promise<IssueContext> { |
| 145 | console.log(`📖 [Context] Fetching ${isPullRequest ? "PR" : "Issue"} #${issueNumber} from ${owner}/${repo}`) |
| 146 | |
| 147 | const token = await getInstallationAccessToken(installationId) |
| 148 | const headers = { |
| 149 | Authorization: `Bearer ${token}`, |
| 150 | Accept: "application/vnd.github+json", |
| 151 | "X-GitHub-Api-Version": "2022-11-28", |
| 152 | "User-Agent": "21st-dev-app", |
| 153 | } |
| 154 | |
| 155 | // Fetch issue or PR details |
| 156 | const detailsUrl = isPullRequest |
| 157 | ? `https://api.github.com/repos/${owner}/${repo}/pulls/${issueNumber}` |
| 158 | : `https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}` |
| 159 | |
| 160 | console.log(`📖 [Context] Fetching details from: ${detailsUrl}`) |
| 161 | |
| 162 | // Fetch details, comments, and commits (for PRs) in parallel |
| 163 | const fetchPromises: Promise<Response>[] = [ |
| 164 | fetch(detailsUrl, { headers }), |
| 165 | fetch( |
| 166 | `https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}/comments?per_page=100`, |
| 167 | { headers } |
| 168 | ), |
| 169 | ] |
| 170 | |
| 171 | // Also fetch commits for PRs |
| 172 | if (isPullRequest) { |
| 173 | fetchPromises.push( |
| 174 | fetch( |
| 175 | `https://api.github.com/repos/${owner}/${repo}/pulls/${issueNumber}/commits?per_page=100`, |
| 176 | { headers } |
| 177 | ) |
| 178 | ) |
| 179 | } |
| 180 | |
| 181 | const responses = await Promise.all(fetchPromises) |
| 182 | const [detailsRes, commentsRes, commitsRes] = responses |
| 183 | |
| 184 | if (!detailsRes.ok) { |
| 185 | console.error(`❌ [Context] Failed to fetch details: ${detailsRes.status}`) |
| 186 | throw new Error(`Failed to fetch issue details: ${detailsRes.status}`) |
| 187 | } |
| 188 | |
| 189 | const details: GitHubIssue | GitHubPullRequest = await detailsRes.json() |
| 190 | const comments: GitHubComment[] = commentsRes.ok ? await commentsRes.json() : [] |
| 191 | const commits: GitHubCommit[] = commitsRes?.ok ? await commitsRes.json() : [] |
| 192 | |
| 193 | console.log(`📖 [Context] Fetched issue: "${details.title}"`) |
| 194 | console.log(`📖 [Context] Author: @${details.user.login}, State: ${details.state}`) |
| 195 | console.log(`📖 [Context] Body length: ${details.body?.length || 0} chars`) |
no test coverage detected