-
Notifications
You must be signed in to change notification settings - Fork 350
feat: add OpenCode engine integration (re-apply PR #18403) #25830
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Copilot
wants to merge
14
commits into
main
Choose a base branch
from
copilot/reapply-previous-pull-request-18403
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
86b3180
feat: add OpenCode engine integration (re-apply PR #18403)
Copilot c249dc9
fix: rename shadowed variable in opencode_mcp.go per review feedback
Copilot 456685d
docs(adr): add draft ADR-25830 for OpenCode engine integration
github-actions[bot] ce0f3e8
fix: address review feedback - prompt arg, dynamic domains, file perm…
Copilot 5eff362
feat: switch OpenCode engine default routing from Anthropic to Copilot
Copilot fa75209
docs: clarify OpenCodeDefaultDomains comment per code review
Copilot 8e2b711
feat: default OpenCode to COPILOT_GITHUB_TOKEN / github.token (copilo…
Copilot 157cd5e
test: add GetSecretValidationStep coverage for OpenCode engine
Copilot 76bb6ca
Merge remote-tracking branch 'origin/main' into copilot/reapply-previ…
Copilot 6272c7a
chore: merge main and recompile workflows
Copilot b18de0a
Merge remote-tracking branch 'origin/main' into copilot/reapply-previ…
Copilot 109cb39
chore: merge main and recompile workflows
Copilot 3b90243
Merge remote-tracking branch 'origin/main' into copilot/reapply-previ…
Copilot a99a96b
chore: merge main and recompile workflows
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| --- | ||
| description: Smoke test workflow that validates OpenCode engine functionality twice daily | ||
| on: | ||
| schedule: every 12h | ||
| workflow_dispatch: | ||
| pull_request: | ||
| types: [labeled] | ||
| names: ["smoke"] | ||
| reaction: "eyes" | ||
| status-comment: true | ||
| permissions: | ||
| contents: read | ||
| issues: read | ||
| pull-requests: read | ||
| name: Smoke OpenCode | ||
| engine: | ||
| id: opencode | ||
| model: anthropic/claude-sonnet-4-20250514 | ||
| strict: true | ||
| imports: | ||
| - shared/gh.md | ||
| - shared/reporting.md | ||
| network: | ||
| allowed: | ||
| - defaults | ||
| - github | ||
| tools: | ||
| cache-memory: true | ||
| github: | ||
| toolsets: [repos, pull_requests] | ||
| edit: | ||
| bash: | ||
| - "*" | ||
| web-fetch: | ||
| safe-outputs: | ||
| add-comment: | ||
| hide-older-comments: true | ||
| max: 2 | ||
| create-issue: | ||
| expires: 2h | ||
| close-older-issues: true | ||
| labels: [automation, testing] | ||
| add-labels: | ||
| allowed: [smoke-opencode] | ||
| messages: | ||
| footer: "> ⚡ *[{workflow_name}]({run_url}) — Powered by OpenCode*" | ||
| run-started: "⚡ OpenCode initializing... [{workflow_name}]({run_url}) begins on this {event_type}..." | ||
| run-success: "🎯 [{workflow_name}]({run_url}) **MISSION COMPLETE!** OpenCode has delivered. ⚡" | ||
| run-failure: "⚠️ [{workflow_name}]({run_url}) {status}. OpenCode encountered unexpected challenges..." | ||
| timeout-minutes: 15 | ||
| --- | ||
|
|
||
| # Smoke Test: OpenCode Engine Validation | ||
|
|
||
| **CRITICAL EFFICIENCY REQUIREMENTS:** | ||
| - Keep ALL outputs extremely short and concise. Use single-line responses. | ||
| - NO verbose explanations or unnecessary context. | ||
| - Minimize file reading - only read what is absolutely necessary for the task. | ||
|
|
||
| ## Test Requirements | ||
|
|
||
| 1. **GitHub MCP Testing**: Use GitHub MCP tools to fetch details of exactly 2 merged pull requests from ${{ github.repository }} (title and number only) | ||
| 2. **Web Fetch Testing**: Use the web-fetch MCP tool to fetch https://github.com and verify the response contains "GitHub" (do NOT use bash or playwright for this test - use the web-fetch MCP tool directly) | ||
| 3. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-opencode-${{ github.run_id }}.txt` with content "Smoke test passed for OpenCode at $(date)" (create the directory if it doesn't exist) | ||
| 4. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) | ||
| 5. **Build gh-aw**: Run `GOCACHE=/tmp/go-cache GOMODCACHE=/tmp/go-mod make build` to verify the agent can successfully build the gh-aw project. If the command fails, mark this test as ❌ and report the failure. | ||
|
|
||
| ## Output | ||
|
|
||
| Add a **very brief** comment (max 5-10 lines) to the current pull request with: | ||
| - ✅ or ❌ for each test result | ||
| - Overall status: PASS or FAIL | ||
|
|
||
| If all tests pass, use the `add_labels` safe-output tool to add the label `smoke-opencode` to the pull request. | ||
|
|
||
| **Important**: If no action is needed after completing your analysis, you **MUST** call the `noop` safe-output tool with a brief explanation. Failing to call any safe-output tool is the most common cause of safe-output workflow failures. | ||
|
|
||
| ```json | ||
| {"noop": {"message": "No action needed: [brief explanation of what was analyzed and why]"}} | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| #!/usr/bin/env bash | ||
| # Convert MCP Gateway Configuration to OpenCode Format | ||
| # This script converts the gateway's standard HTTP-based MCP configuration | ||
| # to the JSON format expected by OpenCode (opencode.jsonc) | ||
| # | ||
| # OpenCode reads MCP server configuration from opencode.jsonc: | ||
| # - Project: ./opencode.jsonc (used here) | ||
| # - Global: ~/.config/opencode/opencode.json | ||
| # | ||
| # See: https://opencode.ai/docs/mcp-servers/ | ||
|
|
||
| set -e | ||
|
|
||
| # Required environment variables: | ||
| # - MCP_GATEWAY_OUTPUT: Path to gateway output configuration file | ||
| # - MCP_GATEWAY_DOMAIN: Domain to use for MCP server URLs (e.g., host.docker.internal) | ||
| # - MCP_GATEWAY_PORT: Port for MCP gateway (e.g., 80) | ||
| # - GITHUB_WORKSPACE: Workspace directory for project-level config | ||
|
|
||
| if [ -z "$MCP_GATEWAY_OUTPUT" ]; then | ||
| echo "ERROR: MCP_GATEWAY_OUTPUT environment variable is required" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ ! -f "$MCP_GATEWAY_OUTPUT" ]; then | ||
| echo "ERROR: Gateway output file not found: $MCP_GATEWAY_OUTPUT" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "$MCP_GATEWAY_DOMAIN" ]; then | ||
| echo "ERROR: MCP_GATEWAY_DOMAIN environment variable is required" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "$MCP_GATEWAY_PORT" ]; then | ||
| echo "ERROR: MCP_GATEWAY_PORT environment variable is required" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "$GITHUB_WORKSPACE" ]; then | ||
| echo "ERROR: GITHUB_WORKSPACE environment variable is required" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "Converting gateway configuration to OpenCode format..." | ||
| echo "Input: $MCP_GATEWAY_OUTPUT" | ||
| echo "Target domain: $MCP_GATEWAY_DOMAIN:$MCP_GATEWAY_PORT" | ||
|
|
||
| # Convert gateway output to OpenCode opencode.jsonc format | ||
| # Gateway format: | ||
| # { | ||
| # "mcpServers": { | ||
| # "server-name": { | ||
| # "type": "http", | ||
| # "url": "http://domain:port/mcp/server-name", | ||
| # "headers": { | ||
| # "Authorization": "apiKey" | ||
| # } | ||
| # } | ||
| # } | ||
| # } | ||
| # | ||
| # OpenCode format: | ||
| # { | ||
| # "mcp": { | ||
| # "server-name": { | ||
| # "type": "remote", | ||
| # "enabled": true, | ||
| # "url": "http://domain:port/mcp/server-name", | ||
| # "headers": { | ||
| # "Authorization": "apiKey" | ||
| # } | ||
| # } | ||
| # } | ||
| # } | ||
| # | ||
| # The main differences: | ||
| # 1. Top-level key is "mcp" not "mcpServers" | ||
| # 2. Server type is "remote" not "http" | ||
| # 3. Has "enabled": true field | ||
| # 4. Remove "tools" field (Copilot-specific) | ||
| # 5. URLs must use the correct domain (host.docker.internal) for container access | ||
|
|
||
| # Build the correct URL prefix using the configured domain and port | ||
| URL_PREFIX="http://${MCP_GATEWAY_DOMAIN}:${MCP_GATEWAY_PORT}" | ||
|
|
||
| OPENCODE_CONFIG_FILE="${GITHUB_WORKSPACE}/opencode.jsonc" | ||
|
|
||
| # Build the MCP section from gateway output | ||
| MCP_SECTION=$(jq --arg urlPrefix "$URL_PREFIX" ' | ||
| .mcpServers | with_entries( | ||
| .value |= { | ||
| "type": "remote", | ||
| "enabled": true, | ||
| "url": (.url | sub("^http://[^/]+/mcp/"; $urlPrefix + "/mcp/")), | ||
| "headers": .headers | ||
| } | ||
| ) | ||
| ' "$MCP_GATEWAY_OUTPUT") | ||
|
|
||
| # Merge into existing opencode.jsonc or create new one | ||
| if [ -f "$OPENCODE_CONFIG_FILE" ]; then | ||
| echo "Merging MCP config into existing opencode.jsonc..." | ||
| jq --argjson mcpSection "$MCP_SECTION" '.mcp = (.mcp // {}) * $mcpSection' "$OPENCODE_CONFIG_FILE" > "${OPENCODE_CONFIG_FILE}.tmp" | ||
| mv "${OPENCODE_CONFIG_FILE}.tmp" "$OPENCODE_CONFIG_FILE" | ||
| else | ||
| echo "Creating new opencode.jsonc..." | ||
| jq -n --argjson mcpSection "$MCP_SECTION" '{"mcp": $mcpSection}' > "$OPENCODE_CONFIG_FILE" | ||
| fi | ||
|
|
||
| echo "OpenCode configuration written to $OPENCODE_CONFIG_FILE" | ||
| echo "" | ||
| echo "Converted configuration:" | ||
| cat "$OPENCODE_CONFIG_FILE" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| --- | ||
| engine: | ||
| id: opencode | ||
| display-name: OpenCode | ||
| description: OpenCode CLI with headless mode and multi-provider LLM support | ||
| runtime-id: opencode | ||
| provider: | ||
| name: opencode | ||
| auth: | ||
| - role: api-key | ||
| secret: ANTHROPIC_API_KEY | ||
| --- | ||
|
|
||
| <!-- # OpenCode CLI | ||
| Shared engine configuration for OpenCode multi-provider AI coding agent (BYOK). --> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This converter writes ${GITHUB_WORKSPACE}/opencode.jsonc, which includes Authorization headers for MCP servers. Unlike convert_gateway_config_gemini.sh/start_mcp_gateway.sh, it doesn’t set a restrictive umask or chmod the output, so the config may be created with overly-permissive mode (e.g., 0644). Consider adding
umask 077,set -euo pipefail, andchmod 600on opencode.jsonc (and any temp files) after writing/merging.