OpenCode Go Node

The OpenCode Go node runs the OpenCode CLI (Go) in an isolated, hardened Heym container against a GitHub repository.

The OpenCode Go node runs the OpenCode CLI (Go) in an isolated, hardened Heym container against a GitHub repository. Like the Codex node, it is designed for coding tasks such as fixing tests, editing files, producing a patch, or opening a pull request — but it uses the provider-agnostic OpenCode Go model gateway instead of OpenAI Codex.

Overview

PropertyValue
Inputs1
Outputs1
CredentialOpenCode Go API key + GitHub
Output$nodeLabel.summary, $nodeLabel.diff, $nodeLabel.changedFiles, $nodeLabel.pullRequestUrl

Authentication

The OpenCode Go credential stores an OpenCode Go gateway API key (from opencode.ai/go) and an optional Gateway Base URL (defaults to https://opencode.ai/zen/go/v1; override only for a self-hosted or proxied gateway).

The node also requires a GitHub credential for cloning private repositories, pushing the working branch, and creating pull requests. The GitHub token is never placed inside the sandbox container — Heym performs all git and GitHub operations on the host, so generated code cannot exfiltrate push credentials.

Isolation and security

Execution isolation is chosen by HEYM_OPENCODE_CLI_COMMAND, exactly like the Codex node:

  • Local development (run.sh) leaves it at the default opencode, so OpenCode runs as a host subprocess against the cloned workspace — no Docker required, no extra flags.
  • Docker deployments (deploy.sh and the single GHCR image) set it to /usr/local/bin/heym-opencode-docker, a wrapper that runs opencode run inside a hardened, throwaway sibling container sharing the OpenCode workspace named volume.

The hardened runner container drops all Linux capabilities, sets no-new-privileges, uses a read-only root with a tmpfs /tmp, and applies pid/memory/CPU limits. Network egress is allowed (OpenCode must reach the model gateway). The GitHub token is never placed inside the container — all git and GitHub operations run host-side, so only the OpenCode API key and repository files are ever inside.

OpenCode only edits files on disk; Heym owns every git/GitHub action.

Models

OpenCode Go's model roster changes often, so the Model field is populated live from the gateway's model list (GET https://opencode.ai/zen/go/v1/models) and shown as a searchable dropdown. If the live list is unavailable, a built-in fallback list is used. Model ids use the opencode-go/<model> form (for example opencode-go/kimi-k3, opencode-go/deepseek-v4-pro, opencode-go/qwen3.7-max) — opencode-go is the OpenCode CLI's provider id for the Go gateway. Leave the field empty to use the runner default (opencode-go/kimi-k3). Model ids saved in the older opencode/<model> form are rewritten automatically at run time.

Fields

FieldDescription
OpenCode Go CredentialOpenCode Go credential (gateway API key)
GitHub CredentialGitHub PAT credential used for repository access
Repository URLHTTPS GitHub repository URL; supports expressions
Base BranchBranch to clone before OpenCode runs, default main
ModelOpenCode Go model (live searchable dropdown, opencode-go/<model>); empty uses the runner default
Reasoning VariantOptional; maps to opencode run --variant for models that support reasoning effort
Task PromptCoding task for OpenCode; supports expressions such as $input.text
Publish ModeHow changes are delivered (see table below)
Branch NameWorking branch for PR/commit modes, default opencode/$executionId
TimeoutMaximum OpenCode execution time in seconds

Publish Modes

ModeWhat it does
diff_onlyEdits files locally and returns the patch and changed files. Nothing is pushed.
draft_prCommits to the branch, pushes it, and opens a draft pull request.
open_prCommits to the branch, pushes it, and opens a review-ready (non-draft) pull request.
commit_pushCommits to the branch and pushes it, without opening a pull request.
direct_commitCommits and pushes straight to the base branch (no separate branch or PR).
open_or_update_prUpdates the agent's existing open PR when one exists — even if the branch name differs, the runner finds it by author + base — otherwise opens a new one. Best for re-runs and "update the open PR" instructions.
update_existing_prAdds a commit to the existing branch/PR; opens one if none exists yet.
patch_artifactSaves the diff as a downloadable file and returns patchUrl. Nothing is pushed.

Outputs

KeyDescription
statusAlways completed (the OpenCode Go node does not pause for input)
summaryOpenCode's final message
validationValidation notes when reported
diffGit patch when files changed
changedFilesChanged file paths
branchNameWorking branch name
pullRequestUrlPR URL in draft_pr, open_pr, open_or_update_pr, and update_existing_pr modes
pushedBranchBranch that was pushed in commit/PR modes
patchUrlDownload link for the diff in patch_artifact mode

UI screenshots on pull requests

For UI/frontend tasks, OpenCode should save PNG screenshots under a gitignored path such as frontend/.e2e-artifacts/ (not in source). If frontend dependencies are missing, the runner prompt allows a targeted package install (for example bun install) plus a short-lived preview/bun run dev solely to capture the UI. Heym uploads those images to a single shared GitHub prerelease (opencode-pr-assets) as assets named <branch>-…, then embeds them in the PR description before the pull request is opened, so a new PR is created already containing its screenshots (existing PRs are updated in place).

OpenCode is also instructed to end with a PR_TITLE: … line so Heym can open the pull request with a meaningful subject instead of placeholders such as Done.

OpenCode sometimes ends a turn mid-task ("…Now let me take a screenshot"), which would finalize the run before the screenshot is captured. To prevent that, the runner prompt requires capturing screenshots before the final message, and if the run still finishes with no publishable summary or with a UI change but no screenshot, Heym runs one more OpenCode pass in the same workspace to finish. If a UI change still has no screenshot afterwards, a visible note is added to the PR body so the gap is never silent.

What gets published to GitHub

Your Task Prompt is private input, not PR content. Only two things are published: a ## Change Summary describing what the code change does, and a ## Screenshots section when screenshots were captured. The PR title is derived from the change summary alone.

The runner prompt states this policy, and Heym also enforces it after the run: before anything is committed or opened as a pull request, it strips prompt-echo sections (## Task, ## Prompt, ## Instructions, ## Original Request, …) and any paragraph copied verbatim from the task prompt out of the summary, the PR body, and the commit message.

Heym reads the ## Change Summary section out of the agent's messages rather than taking whatever it said last, because OpenCode emits a message per step and the final one is often mid-run commentary. Step narration (Both pass. Let me do a final review:) is also rejected as a PR title or commit subject. If the run produces no usable change summary, the pull request falls back to listing the changed files instead of publishing commentary.

As an agent tool

The OpenCode Go node can be attached to an AI Agent node's tool handle so the agent can delegate coding tasks. Configure the credential, GitHub credential, and repository on the node, then mark Task Prompt (and optionally Repository URL) with the agent-provided toggle so the agent supplies them at call time.

Example

{
  "id": "opencode-1",
  "type": "opencodeGo",
  "position": { "x": 420, "y": 120 },
  "data": {
    "label": "fix_pr",
    "credentialId": "opencode-credential-uuid",
    "githubCredentialId": "github-credential-uuid",
    "repositoryUrl": "https://github.com/acme/app",
    "baseBranch": "main",
    "taskPrompt": "$input.text",
    "publishMode": "open_pr",
    "branchName": "opencode/$executionId",
    "opencodeModel": "opencode-go/kimi-k3",
    "timeoutSeconds": 3600
  }
}