Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/actions/setup-bun/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,18 @@ runs:
# Workaround for patched peer variants
# e.g. ./patches/ for standard-openapi
# https://github.com/oven-sh/bun/issues/28147
if [ "$RUNNER_OS" = "Windows" ]; then
bun install --linker hoisted ${{ inputs.install-flags }}
else
bun install ${{ inputs.install-flags }}
install_dependencies() {
if [ "$RUNNER_OS" = "Windows" ]; then
bun install --linker hoisted ${{ inputs.install-flags }}
else
bun install ${{ inputs.install-flags }}
fi
}

if ! install_dependencies; then
echo "Bun install failed; clearing the runner-local Bun cache and retrying"
rm -rf "$(bun pm cache)"
install_dependencies
fi
shell: bash

Expand Down
70 changes: 70 additions & 0 deletions .github/workflows/publish-fork-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: publish-fork-release

on:
workflow_dispatch:
inputs:
version:
description: Release version without the v prefix
required: true
default: 1.18.23
source_run_id:
description: Actions run ID containing the completed desktop artifacts
required: true
default: "33138463284"

permissions:
actions: read
contents: write

jobs:
publish:
runs-on: ubuntu-24.04
env:
OPENCODE_VERSION: ${{ inputs.version }}
SOURCE_RUN_ID: ${{ inputs.source_run_id }}
steps:
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: desktop-*
path: /tmp/desktop
merge-multiple: true
run-id: ${{ inputs.source_run_id }}
github-token: ${{ github.token }}

- name: Upload desktop installers and publish release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
if [[ ! "$SOURCE_RUN_ID" =~ ^[0-9]+$ ]]; then
echo "source_run_id must be numeric"
exit 1
fi
if [[ "$(gh release view "v${OPENCODE_VERSION}" --json isDraft --jq .isDraft --repo "${GITHUB_REPOSITORY}")" != "true" ]]; then
echo "Release v${OPENCODE_VERSION} is missing or already published"
exit 1
fi
mapfile -d '' files < <(find /tmp/desktop -mindepth 1 -maxdepth 1 -type f \( \
-name 'opencode-desktop-*.AppImage' -o \
-name 'opencode-desktop-*.blockmap' -o \
-name 'opencode-desktop-*.deb' -o \
-name 'opencode-desktop-*.dmg' -o \
-name 'opencode-desktop-*.exe' -o \
-name 'opencode-desktop-*.rpm' -o \
-name 'opencode-desktop-*.tar.gz' -o \
-name 'opencode-desktop-*.zip' -o \
-name 'latest.json' -o \
-name 'latest*.yml' \
\) -print0)
if (( ${#files[@]} == 0 )); then
echo "No desktop release assets found"
exit 1
fi
printf 'Uploading %s\n' "${files[@]}"
gh release upload "v${OPENCODE_VERSION}" "${files[@]}" \
--clobber \
--repo "${GITHUB_REPOSITORY}"
gh release edit "v${OPENCODE_VERSION}" \
--draft=false \
--latest \
--repo "${GITHUB_REPOSITORY}"
180 changes: 180 additions & 0 deletions .github/workflows/release-fork.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
name: release-fork

on:
workflow_dispatch:
inputs:
version:
description: "Release version without the v prefix"
required: true
default: "1.18.23"
type: string

permissions:
contents: write

concurrency:
group: release-fork-${{ inputs.version }}
cancel-in-progress: false

env:
OPENCODE_VERSION: ${{ inputs.version }}
OPENCODE_CHANNEL: prod

jobs:
create-release:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v4.3.0
with:
fetch-depth: 0

- name: Create draft release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
if gh release view "v${OPENCODE_VERSION}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
if [ "$(gh release view "v${OPENCODE_VERSION}" --repo "${GITHUB_REPOSITORY}" --json isDraft --jq .isDraft)" != "true" ]; then
echo "Published release v${OPENCODE_VERSION} already exists"
exit 1
fi
echo "Reusing existing draft release v${OPENCODE_VERSION}"
exit 0
fi
gh release create "v${OPENCODE_VERSION}" \
--draft \
--generate-notes \
--target "${GITHUB_SHA}" \
--title "v${OPENCODE_VERSION}" \
--repo "${GITHUB_REPOSITORY}"

build-cli:
needs: create-release
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v4.3.0

- uses: ./.github/actions/setup-bun

- name: Build CLI archives
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
OPENCODE_RELEASE: "true"
run: |
./packages/opencode/script/build.ts
./packages/cli/script/build.ts

build-desktop:
needs: create-release
strategy:
fail-fast: false
matrix:
settings:
- host: macos-26-intel
target: x86_64-apple-darwin
platform_flag: --mac --x64
bun_install_flags: --os=darwin --cpu=x64
- host: macos-26
target: aarch64-apple-darwin
platform_flag: --mac --arm64
bun_install_flags: --os=darwin --cpu=arm64
- host: windows-2025
target: aarch64-pc-windows-msvc
platform_flag: --win --arm64
- host: windows-2025
target: x86_64-pc-windows-msvc
platform_flag: --win
bun_install_flags: --os=win32 --cpu=x64
- host: ubuntu-24.04
target: x86_64-unknown-linux-gnu
platform_flag: --linux
- host: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
platform_flag: --linux --arm64
runs-on: ${{ matrix.settings.host }}
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v4.3.0

- uses: ./.github/actions/setup-bun
with:
install-flags: ${{ matrix.settings.bun_install_flags }}

- name: Install Linux packaging tools
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends rpm

- name: Prepare desktop build
working-directory: packages/desktop
run: bun ./scripts/prepare.ts
env:
OPENCODE_VERSION: ${{ env.OPENCODE_VERSION }}
OPENCODE_CHANNEL: prod
RUST_TARGET: ${{ matrix.settings.target }}

- name: Build desktop application
working-directory: packages/desktop
run: bun run build
env:
NODE_OPTIONS: --max-old-space-size=4096
OPENCODE_VERSION: ${{ env.OPENCODE_VERSION }}
OPENCODE_CHANNEL: prod
RUST_TARGET: ${{ matrix.settings.target }}
OPENCODE_UNSIGNED_BUILD: "true"

- name: Package desktop installer
working-directory: packages/desktop
run: npx electron-builder ${{ matrix.settings.platform_flag }} --publish never --config electron-builder.config.ts
env:
GITHUB_ACTIONS: "false"
CSC_IDENTITY_AUTO_DISCOVERY: "false"
OPENCODE_CHANNEL: prod
OPENCODE_UNSIGNED_BUILD: "true"

- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: desktop-${{ matrix.settings.target }}
path: packages/desktop/dist/*

publish-release:
needs:
- build-cli
- build-desktop
runs-on: ubuntu-24.04
steps:
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: desktop-*
path: /tmp/desktop
merge-multiple: true

- name: Upload desktop installers and publish release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mapfile -d '' files < <(find /tmp/desktop -mindepth 1 -maxdepth 1 -type f \( \
-name 'opencode-desktop-*.AppImage' -o \
-name 'opencode-desktop-*.blockmap' -o \
-name 'opencode-desktop-*.deb' -o \
-name 'opencode-desktop-*.dmg' -o \
-name 'opencode-desktop-*.exe' -o \
-name 'opencode-desktop-*.rpm' -o \
-name 'opencode-desktop-*.tar.gz' -o \
-name 'opencode-desktop-*.zip' -o \
-name 'latest.json' -o \
-name 'latest*.yml' \
\) -print0)
if (( ${#files[@]} == 0 )); then
echo "No desktop release assets found"
exit 1
fi
gh release upload "v${OPENCODE_VERSION}" "${files[@]}" \
--clobber \
--repo "${GITHUB_REPOSITORY}"
gh release edit "v${OPENCODE_VERSION}" \
--draft=false \
--latest \
--repo "${GITHUB_REPOSITORY}"
8 changes: 5 additions & 3 deletions packages/desktop/electron-builder.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const execFileAsync = promisify(execFile)
const packageDir = path.dirname(fileURLToPath(import.meta.url))
const rootDir = path.resolve(packageDir, "../..")
const signScript = path.join(rootDir, "script", "sign-windows.ps1")
const unsignedBuild = process.env.OPENCODE_UNSIGNED_BUILD === "true"
// The Electron 42 packaging update briefly installed Linux launchers/icons under
// "opencode-desktop". Keep that hidden desktop entry around so existing GNOME/KDE
// pins still resolve after the canonical app id changes back to ai.opencode.desktop.
Expand All @@ -19,6 +20,7 @@ const metainfoFpm = (appId: string) =>
`${path.join(packageDir, "resources", `${appId}.metainfo.xml`)}=/usr/share/metainfo/${appId}.metainfo.xml`

async function signWindows(configuration: { path: string }) {
if (unsignedBuild) return
if (process.platform !== "win32") return
if (process.env.GITHUB_ACTIONS !== "true") return

Expand Down Expand Up @@ -75,15 +77,15 @@ const getBase = (appId: string): Configuration => ({
mac: {
category: "public.app-category.developer-tools",
icon: `resources/icons/icon.icns`,
hardenedRuntime: true,
hardenedRuntime: !unsignedBuild,
gatekeeperAssess: false,
entitlements: "resources/entitlements.plist",
entitlementsInherit: "resources/entitlements.plist",
notarize: true,
notarize: !unsignedBuild,
target: ["dmg", "zip"],
},
dmg: {
sign: true,
sign: !unsignedBuild,
},
protocols: {
name: "OpenCode",
Expand Down
6 changes: 6 additions & 0 deletions packages/tui/src/component/prompt/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export function Prompt(props: PromptProps) {
const stash = usePromptStash()
const keymap = useOpencodeKeymap()
const agentShortcut = useCommandShortcut("agent.cycle")
const variantShortcut = useCommandShortcut("variant.cycle")
const paletteShortcut = useCommandShortcut("command.palette.show")
const renderer = useRenderer()
const exit = useExit()
Expand Down Expand Up @@ -1675,6 +1676,11 @@ export function Prompt(props: PromptProps) {
</text>
</Match>
</Switch>
<Show when={local.model.variant.list().length > 0 && variantShortcut()}>
<text fg={theme.text}>
{variantShortcut()} <span style={{ fg: theme.textMuted }}>thinking</span>
</text>
</Show>
<text fg={theme.text}>
{paletteShortcut()} <span style={{ fg: theme.textMuted }}>commands</span>
</text>
Expand Down
Loading