feat(opencode): launch Opencode AI session from PR list#3
feat(opencode): launch Opencode AI session from PR list#3OctavianTocan wants to merge 1 commit intomainfrom
Conversation
…a PR Press 'o' on a selected PR to fire off a headless Opencode session with the PR number and repo, then open the Opencode desktop app where the session appears for interactive follow-up. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reviewer's GuideAdds a new Sequence diagram for launching Opencode session from PR listsequenceDiagram
actor User
participant LsCommand
participant OpencodeModule
participant BunRuntime
participant OpencodeCLI
participant OpencodeDesktopApp
User->>LsCommand: Press key o on selected PR
LsCommand->>OpencodeModule: import ../lib/opencode
OpencodeModule-->>LsCommand: launchOpencode
LsCommand->>OpencodeModule: launchOpencode(selectedPR)
OpencodeModule->>OpencodeModule: Build title and prompt from pr
OpencodeModule->>BunRuntime: Bun.spawn([opencode, run, --title, title, prompt])
BunRuntime->>OpencodeCLI: Start headless opencode run session
BunRuntime->>BunRuntime: proc.unref()
OpencodeModule->>BunRuntime: Bun.spawn([open, -a, Opencode])
BunRuntime->>OpencodeDesktopApp: Open Opencode application
BunRuntime->>BunRuntime: app.unref()
LsCommand-->>User: showFlash(Opening Opencode for #n...) and remain responsive
Class diagram for Opencode PR session launcherclassDiagram
class PullRequest {
+number number
+title string
+repo string
+url string
}
class OpencodeModule {
+launchOpencode(pr PullRequest) void
}
class BunRuntime {
+spawn(args string[], options object) Process
}
class Process {
+unref() void
}
OpencodeModule ..> PullRequest : uses
OpencodeModule ..> BunRuntime : spawns processes
BunRuntime ..> Process : returns
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The dynamic import and
launchOpencodecall in the key handler fire-and-forget without any error handling; consider catching failures and surfacing a flash message so users understand when Opencode fails to launch. - The
open -a Opencodesubprocess is macOS-specific; if this command is used in non-macOS environments, consider gating it behind a platform check or using a more portable way to launch the desktop app.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The dynamic import and `launchOpencode` call in the key handler fire-and-forget without any error handling; consider catching failures and surfacing a flash message so users understand when Opencode fails to launch.
- The `open -a Opencode` subprocess is macOS-specific; if this command is used in non-macOS environments, consider gating it behind a platform check or using a more portable way to launch the desktop app.
## Individual Comments
### Comment 1
<location path="src/lib/opencode.ts" line_range="37-41" />
<code_context>
+ proc.unref()
+
+ // Open the Opencode desktop app so the user can see the session
+ const app = Bun.spawn(
+ ["open", "-a", "Opencode"],
+ { stdout: "ignore", stderr: "ignore" },
+ )
+ app.unref()
+}
</code_context>
<issue_to_address>
**suggestion:** The `open -a Opencode` command is macOS-specific and may limit portability.
This relies on macOS and the app being installed as `Opencode`, and will silently do nothing on other platforms or headless environments. Consider guarding by platform, making it a no-op where unsupported, or letting users configure the launch command so non-macOS environments can still work.
Suggested implementation:
```typescript
// Fire and forget: spawn opencode run in the background
const proc = Bun.spawn(
["opencode", "run", "--title", title, prompt],
{ stdout: "ignore", stderr: "ignore", stdin: "ignore" },
)
// Detach so raft can exit independently
proc.unref()
// Optionally open the Opencode desktop app so the user can see the session.
// This is macOS-specific by default, but can be overridden via OPENCODE_OPEN_COMMAND.
const openCommand = process.env.OPENCODE_OPEN_COMMAND
if (openCommand) {
// Allow users to configure a custom launch command, e.g. "opencode-desktop --focus"
const [cmd, ...args] = openCommand.split(" ").filter(Boolean)
if (cmd) {
const app = Bun.spawn([cmd, ...args], {
stdout: "ignore",
stderr: "ignore",
stdin: "ignore",
})
app.unref()
}
} else if (process.platform === "darwin") {
// Default macOS behavior: open the Opencode app if available
const app = Bun.spawn(
["open", "-a", "Opencode"],
{ stdout: "ignore", stderr: "ignore", stdin: "ignore" },
)
app.unref()
}
}
```
If you already have a central configuration mechanism, you may want to:
1. Replace direct `process.env.OPENCODE_OPEN_COMMAND` access with your config loader.
2. Document the `OPENCODE_OPEN_COMMAND` env var (or equivalent config key) so non-macOS/headless users know how to disable or customize the launch behavior.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| const app = Bun.spawn( | ||
| ["open", "-a", "Opencode"], | ||
| { stdout: "ignore", stderr: "ignore" }, | ||
| ) | ||
| app.unref() |
There was a problem hiding this comment.
suggestion: The open -a Opencode command is macOS-specific and may limit portability.
This relies on macOS and the app being installed as Opencode, and will silently do nothing on other platforms or headless environments. Consider guarding by platform, making it a no-op where unsupported, or letting users configure the launch command so non-macOS environments can still work.
Suggested implementation:
// Fire and forget: spawn opencode run in the background
const proc = Bun.spawn(
["opencode", "run", "--title", title, prompt],
{ stdout: "ignore", stderr: "ignore", stdin: "ignore" },
)
// Detach so raft can exit independently
proc.unref()
// Optionally open the Opencode desktop app so the user can see the session.
// This is macOS-specific by default, but can be overridden via OPENCODE_OPEN_COMMAND.
const openCommand = process.env.OPENCODE_OPEN_COMMAND
if (openCommand) {
// Allow users to configure a custom launch command, e.g. "opencode-desktop --focus"
const [cmd, ...args] = openCommand.split(" ").filter(Boolean)
if (cmd) {
const app = Bun.spawn([cmd, ...args], {
stdout: "ignore",
stderr: "ignore",
stdin: "ignore",
})
app.unref()
}
} else if (process.platform === "darwin") {
// Default macOS behavior: open the Opencode app if available
const app = Bun.spawn(
["open", "-a", "Opencode"],
{ stdout: "ignore", stderr: "ignore", stdin: "ignore" },
)
app.unref()
}
}
If you already have a central configuration mechanism, you may want to:
- Replace direct
process.env.OPENCODE_OPEN_COMMANDaccess with your config loader. - Document the
OPENCODE_OPEN_COMMANDenv var (or equivalent config key) so non-macOS/headless users know how to disable or customize the launch behavior.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2838242764
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import("../lib/opencode").then(({ launchOpencode }) => { | ||
| launchOpencode(selectedPR) | ||
| showFlash(`Opening Opencode for #${selectedPR.number}...`) |
There was a problem hiding this comment.
Catch Opencode launch failures in key handler
Pressing o can crash raft when Opencode is not installed: launchOpencode calls Bun.spawn, which throws synchronously if opencode (or the later open -a Opencode) is unavailable, and this promise chain has no .catch(...). In Bun, that becomes an unhandled rejection and exits the process, so a documented shortcut can terminate the TUI on machines missing Opencode.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Adds an o keybinding to the PR list workflow to kick off an Opencode AI review session for the currently selected PR, and updates the UI hinting accordingly.
Changes:
- Introduces
src/lib/opencode.tsto spawn a headlessopencode runsession and open the Opencode desktop app. - Wires the
okeybinding inraft lsto invokelaunchOpencode()for the selected PR. - Updates the status/help footer text to advertise the new keybinding.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/lib/opencode.ts | New helper to launch Opencode sessions via subprocess spawning. |
| src/components/status-view.tsx | Updates keybinding hint text to include o: opencode. |
| src/commands/ls.tsx | Adds o keybinding handler to trigger Opencode launch for selected PR. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Fire and forget: spawn opencode run in the background | ||
| const proc = Bun.spawn( | ||
| ["opencode", "run", "--title", title, prompt], | ||
| { stdout: "ignore", stderr: "ignore", stdin: "ignore" }, | ||
| ) | ||
| // Detach so raft can exit independently | ||
| proc.unref() |
| const proc = Bun.spawn( | ||
| ["opencode", "run", "--title", title, prompt], | ||
| { stdout: "ignore", stderr: "ignore", stdin: "ignore" }, | ||
| ) | ||
| // Detach so raft can exit independently | ||
| proc.unref() | ||
|
|
||
| // Open the Opencode desktop app so the user can see the session | ||
| const app = Bun.spawn( | ||
| ["open", "-a", "Opencode"], | ||
| { stdout: "ignore", stderr: "ignore" }, | ||
| ) | ||
| app.unref() |
| // Open the Opencode desktop app so the user can see the session | ||
| const app = Bun.spawn( | ||
| ["open", "-a", "Opencode"], | ||
| { stdout: "ignore", stderr: "ignore" }, | ||
| ) | ||
| app.unref() |
| import("../lib/opencode").then(({ launchOpencode }) => { | ||
| launchOpencode(selectedPR) | ||
| showFlash(`Opening Opencode for #${selectedPR.number}...`) | ||
| }) |
Summary
okeybinding in the PR list view to launch a headless Opencode session for the selected PRTest plan
raft lsand presso🤖 Generated with Claude Code
Summary by Sourcery
Add support for launching an Opencode AI review session directly from the PR list and expose it via a new keyboard shortcut.
New Features:
okeybinding in the PR list to start an Opencode AI session for the selected pull request.opencode runsession for a PR and opens the Opencode desktop app.