()
| 276 | } |
| 277 | |
| 278 | async function installGitHubApp() { |
| 279 | const s = prompts.spinner() |
| 280 | s.start("Installing GitHub app") |
| 281 | |
| 282 | // Get installation |
| 283 | const installation = await getInstallation() |
| 284 | if (installation) return s.stop("GitHub app already installed") |
| 285 | |
| 286 | // Open browser |
| 287 | const url = "https://github.com/apps/opencode-agent" |
| 288 | const command = |
| 289 | process.platform === "darwin" |
| 290 | ? `open "${url}"` |
| 291 | : process.platform === "win32" |
| 292 | ? `start "" "${url}"` |
| 293 | : `xdg-open "${url}"` |
| 294 | |
| 295 | exec(command, (error) => { |
| 296 | if (error) { |
| 297 | prompts.log.warn(`Could not open browser. Please visit: ${url}`) |
| 298 | } |
| 299 | }) |
| 300 | |
| 301 | // Wait for installation |
| 302 | s.message("Waiting for GitHub app to be installed") |
| 303 | const MAX_RETRIES = 120 |
| 304 | let retries = 0 |
| 305 | do { |
| 306 | const installation = await getInstallation() |
| 307 | if (installation) break |
| 308 | |
| 309 | if (retries > MAX_RETRIES) { |
| 310 | s.stop( |
| 311 | `Failed to detect GitHub app installation. Make sure to install the app for the \`${app.owner}/${app.repo}\` repository.`, |
| 312 | ) |
| 313 | throw new UI.CancelledError() |
| 314 | } |
| 315 | |
| 316 | retries++ |
| 317 | await sleep(1000) |
| 318 | } while (true) // oxlint-disable-line no-constant-condition |
| 319 | |
| 320 | s.stop("Installed GitHub app") |
| 321 | |
| 322 | async function getInstallation() { |
| 323 | return await fetch(`https://api.opencode.ai/get_github_app_installation?owner=${app.owner}&repo=${app.repo}`) |
| 324 | .then((res) => res.json()) |
| 325 | .then((data) => data.installation) |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | async function addWorkflowFiles() { |
| 330 | const envStr = |
no test coverage detected