Skip to content

feat(opencode): launch Opencode AI session from PR list#3

Open
OctavianTocan wants to merge 1 commit intomainfrom
claude/nostalgic-antonelli
Open

feat(opencode): launch Opencode AI session from PR list#3
OctavianTocan wants to merge 1 commit intomainfrom
claude/nostalgic-antonelli

Conversation

@OctavianTocan
Copy link
Copy Markdown
Owner

@OctavianTocan OctavianTocan commented Mar 18, 2026

Summary

  • Adds o keybinding in the PR list view to launch a headless Opencode session for the selected PR
  • Opens the Opencode desktop app where the session appears for interactive follow-up
  • Prompt is minimal (PR number, repo, URL) so Opencode fetches details itself

Test plan

  • Select a PR in raft ls and press o
  • Verify Opencode desktop app opens with the new session
  • Verify raft remains responsive after launching

🤖 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:

  • Introduce an o keybinding in the PR list to start an Opencode AI session for the selected pull request.
  • Add an Opencode integration utility that spawns a background opencode run session for a PR and opens the Opencode desktop app.

…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>
Copilot AI review requested due to automatic review settings March 18, 2026 16:15
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Mar 18, 2026

Reviewer's Guide

Adds a new o keybinding on the PR list to launch a background Opencode AI review session for the selected PR and opens the Opencode desktop app, implemented via a new helper in src/lib/opencode.ts and corresponding UI hint updates.

Sequence diagram for launching Opencode session from PR list

sequenceDiagram
  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
Loading

Class diagram for Opencode PR session launcher

classDiagram
  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
Loading

File-Level Changes

Change Details Files
Add o keybinding in the PR list to trigger launching an Opencode AI session for the selected PR.
  • Extend PR list key handler to listen for the o key when a PR is selected.
  • Dynamically import the Opencode helper module and invoke the launcher with the selected pull request object.
  • Show a transient flash message indicating that Opencode is being opened for the selected PR.
src/commands/ls.tsx
Update the status view footer hint text to document the new o keybinding for Opencode.
  • Modify the footer help text to add o: opencode alongside existing keybindings while preserving current layout and wording.
src/components/status-view.tsx
Introduce an Opencode integration helper that spawns a background Opencode session for a PR and opens the desktop app.
  • Define launchOpencode that builds a title and minimal prompt string from the pull request metadata (number, title, repo, URL).
  • Use Bun.spawn to fire-and-forget an opencode run process with ignored stdio and unref so it does not block raft exit.
  • Spawn open -a Opencode (also unref’d) to launch the Opencode desktop app with suppressed stdio output.
src/lib/opencode.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • 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.
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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +37 to +41
const app = Bun.spawn(
["open", "-a", "Opencode"],
{ stdout: "ignore", stderr: "ignore" },
)
app.unref()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  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.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +563 to +565
import("../lib/opencode").then(({ launchOpencode }) => {
launchOpencode(selectedPR)
showFlash(`Opening Opencode for #${selectedPR.number}...`)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.ts to spawn a headless opencode run session and open the Opencode desktop app.
  • Wires the o keybinding in raft ls to invoke launchOpencode() 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.

Comment on lines +28 to +34
// 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()
Comment on lines +29 to +41
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()
Comment on lines +36 to +41
// 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()
Comment on lines +563 to +566
import("../lib/opencode").then(({ launchOpencode }) => {
launchOpencode(selectedPR)
showFlash(`Opening Opencode for #${selectedPR.number}...`)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants