Merge branch 'dev' into fix/acp-show-proper-run-command-message

This commit is contained in:
Mert Can Demir
2026-01-30 14:01:24 +03:00
committed by GitHub
51 changed files with 693 additions and 190 deletions

View File

@@ -3,20 +3,17 @@ description: "Setup Bun with caching and install dependencies"
runs:
using: "composite"
steps:
- name: Mount Bun Cache
uses: useblacksmith/stickydisk@v1
with:
key: ${{ github.repository }}-bun-cache
path: ~/.bun
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version-file: package.json
- name: Cache ~/.bun
id: cache-bun
uses: actions/cache@v4
with:
path: ~/.bun
key: ${{ runner.os }}-bun-${{ hashFiles('package.json') }}-${{ hashFiles('bun.lockb', 'bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-${{ hashFiles('package.json') }}-
- name: Install dependencies
run: bun install
shell: bash

View File

@@ -0,0 +1,42 @@
name: "Setup Git Committer"
description: "Create app token and configure git user"
inputs:
opencode-app-id:
description: "OpenCode GitHub App ID"
required: true
opencode-app-secret:
description: "OpenCode GitHub App private key"
required: true
outputs:
token:
description: "GitHub App token"
value: ${{ steps.apptoken.outputs.token }}
app-slug:
description: "GitHub App slug"
value: ${{ steps.apptoken.outputs.app-slug }}
runs:
using: "composite"
steps:
- name: Create app token
id: apptoken
uses: actions/create-github-app-token@v2
with:
app-id: ${{ inputs.opencode-app-id }}
private-key: ${{ inputs.opencode-app-secret }}
- name: Configure git user
run: |
slug="${{ steps.apptoken.outputs.app-slug }}"
git config --global user.name "${slug}[bot]"
git config --global user.email "${slug}[bot]@users.noreply.github.com"
shell: bash
- name: Clear checkout auth
run: |
git config --local --unset-all http.https://github.com/.extraheader || true
shell: bash
- name: Configure git remote
run: |
git remote set-url origin https://x-access-token:${{ steps.apptoken.outputs.token }}@github.com/${{ github.repository }}
shell: bash

View File

@@ -15,7 +15,7 @@ jobs:
runs-on: blacksmith-4vcpu-ubuntu-2404
permissions:
contents: write
pull-requests: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

45
.github/workflows/containers.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: containers
on:
push:
branches:
- dev
paths:
- packages/containers/**
- .github/workflows/containers.yml
- package.json
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
build:
runs-on: blacksmith-4vcpu-ubuntu-2404
env:
REGISTRY: ghcr.io/${{ github.repository_owner }}
TAG: "24.04"
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-bun
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push containers
run: bun ./packages/containers/script/build.ts --push
env:
REGISTRY: ${{ env.REGISTRY }}
TAG: ${{ env.TAG }}

View File

@@ -16,14 +16,17 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.ref || github.ref_name }}
- name: Setup Bun
uses: ./.github/actions/setup-bun
- name: Setup git committer
id: committer
uses: ./.github/actions/setup-git-committer
with:
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
- name: Generate
run: ./script/generate.ts
@@ -33,10 +36,8 @@ jobs:
echo "No changes to commit"
exit 0
fi
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add -A
git commit -m "chore: generate"
git commit -m "chore: generate" --allow-empty
git push origin HEAD:${{ github.ref_name }} --no-verify
# if ! git push origin HEAD:${{ github.event.pull_request.head.ref || github.ref_name }} --no-verify; then
# echo ""

View File

@@ -36,14 +36,16 @@ jobs:
ref: ${{ github.head_ref || github.ref_name }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
- name: Setup git committer
id: committer
uses: ./.github/actions/setup-git-committer
with:
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
- name: Setup Nix
uses: nixbuild/nix-quick-install-action@v34
- name: Configure git
run: |
git config --global user.email "action@github.com"
git config --global user.name "Github Action"
- name: Pull latest changes
env:
TARGET_BRANCH: ${{ github.head_ref || github.ref_name }}

View File

@@ -37,8 +37,14 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
fetch-depth: 0
- uses: ./.github/actions/setup-bun
- name: Install OpenCode
if: inputs.bump || inputs.version
run: bun i -g opencode-ai
- id: version
run: |
./script/version.ts
@@ -46,6 +52,7 @@ jobs:
GH_TOKEN: ${{ github.token }}
OPENCODE_BUMP: ${{ inputs.bump }}
OPENCODE_VERSION: ${{ inputs.version }}
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
outputs:
version: ${{ steps.version.outputs.version }}
release: ${{ steps.version.outputs.release }}
@@ -58,7 +65,6 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
fetch-tags: true
- uses: ./.github/actions/setup-bun
@@ -103,7 +109,6 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
fetch-tags: true
- uses: apple-actions/import-codesign-certs@v2
@@ -128,6 +133,15 @@ jobs:
- uses: ./.github/actions/setup-bun
- name: Cache apt packages
if: contains(matrix.settings.host, 'ubuntu')
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: ${{ runner.os }}-${{ matrix.settings.target }}-apt-${{ hashFiles('.github/workflows/publish.yml') }}
restore-keys: |
${{ runner.os }}-${{ matrix.settings.target }}-apt-
- name: install dependencies (ubuntu only)
if: contains(matrix.settings.host, 'ubuntu')
run: |
@@ -149,8 +163,8 @@ jobs:
cd packages/desktop
bun ./scripts/prepare.ts
env:
OPENCODE_VERSION: ${{ needs.publish.outputs.version }}
GITHUB_TOKEN: ${{ secrets.SST_GITHUB_TOKEN }}
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
RUST_TARGET: ${{ matrix.settings.target }}
GH_TOKEN: ${{ github.token }}
GITHUB_RUN_ID: ${{ github.run_id }}
@@ -196,12 +210,8 @@ jobs:
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Install OpenCode
if: inputs.bump || inputs.version
run: bun i -g opencode-ai
- uses: ./.github/actions/setup-bun
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
@@ -221,19 +231,26 @@ jobs:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Setup Git Identity
run: |
git config --global user.email "opencode@sst.dev"
git config --global user.name "opencode"
git remote set-url origin https://x-access-token:${{ secrets.SST_GITHUB_TOKEN }}@github.com/${{ github.repository }}
- uses: ./.github/actions/setup-bun
- name: Setup git committer
id: committer
uses: ./.github/actions/setup-git-committer
with:
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
- uses: actions/download-artifact@v4
with:
name: opencode-cli
path: packages/opencode/dist
- name: Cache apt packages (AUR)
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: ${{ runner.os }}-apt-aur-${{ hashFiles('.github/workflows/publish.yml') }}
restore-keys: |
${{ runner.os }}-apt-aur-
- name: Setup SSH for AUR
run: |
sudo apt-get update
@@ -250,6 +267,5 @@ jobs:
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
OPENCODE_RELEASE: ${{ needs.version.outputs.release }}
AUR_KEY: ${{ secrets.AUR_KEY }}
GITHUB_TOKEN: ${{ secrets.SST_GITHUB_TOKEN }}
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
NPM_CONFIG_PROVENANCE: false

View File

@@ -1,6 +1,7 @@
- To regenerate the JavaScript SDK, run `./packages/sdk/js/script/build.ts`.
- ALWAYS USE PARALLEL TOOLS WHEN APPLICABLE.
- The default branch in this repo is `dev`.
- Prefer automation: execute requested actions without confirmation unless blocked by missing info or safety/irreversibility.
## Style Guide

View File

@@ -23,7 +23,7 @@
},
"packages/app": {
"name": "@opencode-ai/app",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode-ai/sdk": "workspace:*",
@@ -73,7 +73,7 @@
},
"packages/console/app": {
"name": "@opencode-ai/console-app",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@ibm/plex": "6.4.1",
@@ -107,7 +107,7 @@
},
"packages/console/core": {
"name": "@opencode-ai/console-core",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@aws-sdk/client-sts": "3.782.0",
"@jsx-email/render": "1.1.1",
@@ -134,7 +134,7 @@
},
"packages/console/function": {
"name": "@opencode-ai/console-function",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@ai-sdk/anthropic": "2.0.0",
"@ai-sdk/openai": "2.0.2",
@@ -158,7 +158,7 @@
},
"packages/console/mail": {
"name": "@opencode-ai/console-mail",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
@@ -182,7 +182,7 @@
},
"packages/desktop": {
"name": "@opencode-ai/desktop",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@opencode-ai/app": "workspace:*",
"@opencode-ai/ui": "workspace:*",
@@ -213,7 +213,7 @@
},
"packages/enterprise": {
"name": "@opencode-ai/enterprise",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@opencode-ai/ui": "workspace:*",
"@opencode-ai/util": "workspace:*",
@@ -242,7 +242,7 @@
},
"packages/function": {
"name": "@opencode-ai/function",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@octokit/auth-app": "8.0.1",
"@octokit/rest": "catalog:",
@@ -258,7 +258,7 @@
},
"packages/opencode": {
"name": "opencode",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"bin": {
"opencode": "./bin/opencode",
},
@@ -362,7 +362,7 @@
},
"packages/plugin": {
"name": "@opencode-ai/plugin",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@opencode-ai/sdk": "workspace:*",
"zod": "catalog:",
@@ -382,7 +382,7 @@
},
"packages/sdk/js": {
"name": "@opencode-ai/sdk",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"devDependencies": {
"@hey-api/openapi-ts": "0.90.10",
"@tsconfig/node22": "catalog:",
@@ -393,7 +393,7 @@
},
"packages/slack": {
"name": "@opencode-ai/slack",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@opencode-ai/sdk": "workspace:*",
"@slack/bolt": "^3.17.1",
@@ -406,7 +406,7 @@
},
"packages/ui": {
"name": "@opencode-ai/ui",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode-ai/sdk": "workspace:*",
@@ -448,7 +448,7 @@
},
"packages/util": {
"name": "@opencode-ai/util",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"zod": "catalog:",
},
@@ -459,7 +459,7 @@
},
"packages/web": {
"name": "@opencode-ai/web",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@astrojs/cloudflare": "12.6.3",
"@astrojs/markdown-remark": "6.3.1",

View File

@@ -1,8 +1,8 @@
{
"nodeModules": {
"x86_64-linux": "sha256-yAtZlh6YR78RwPt0LK/7Pk0qUm0/97+s6ghhZzuoE/0=",
"aarch64-linux": "sha256-6j81rdjQ7Wps9bvfw+mmdwW5p01qUOwX40UZltCTe3Y=",
"aarch64-darwin": "sha256-pDM8M/QMWR6Go5pz3XXsJqcJDHAlHrx2Faijjkzcngo=",
"x86_64-darwin": "sha256-eOAPtMd1n5xYupBOevCLhY1eFy3wzGqFk/EsZocl9Y8="
"x86_64-linux": "sha256-gUWzUsk81miIrjg0fZQmsIQG4pZYmEHgzN6BaXI+lfc=",
"aarch64-linux": "sha256-gwEG75ha/ojTO2iAObTmLTtEkXIXJ7BThzfI5CqlJh8=",
"aarch64-darwin": "sha256-20RGG2GkUItCzD67gDdoSLfexttM8abS//FKO9bfjoM=",
"x86_64-darwin": "sha256-i2VawFuR1UbjPVYoybU6aJDJfFo0tcvtl1aM31Y2mTQ="
}
}

View File

@@ -0,0 +1,25 @@
import { test, expect } from "./fixtures"
import { modelVariantCycleSelector } from "./utils"
test("smoke model variant cycle updates label", async ({ page, gotoSession }) => {
await gotoSession()
await page.addStyleTag({
content: `${modelVariantCycleSelector} { display: inline-block !important; }`,
})
const button = page.locator(modelVariantCycleSelector)
const exists = (await button.count()) > 0
test.skip(!exists, "current model has no variants")
if (!exists) return
await expect(button).toBeVisible()
const before = (await button.innerText()).trim()
await button.click()
await expect(button).not.toHaveText(before)
const after = (await button.innerText()).trim()
await button.click()
await expect(button).not.toHaveText(after)
})

View File

@@ -12,6 +12,7 @@ export const terminalToggleKey = "Control+Backquote"
export const promptSelector = '[data-component="prompt-input"]'
export const terminalSelector = '[data-component="terminal"]'
export const modelVariantCycleSelector = '[data-action="model-variant-cycle"]'
export function createSdk(directory?: string) {
return createOpencodeClient({ baseUrl: serverUrl, directory, throwOnError: true })

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/app",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"description": "",
"type": "module",
"exports": {

View File

@@ -34,11 +34,14 @@ export const DialogSelectModelUnpaid: Component = () => {
})
return (
<Dialog title={language.t("dialog.model.select.title")}>
<div class="flex flex-col gap-3 px-2.5 flex-1 min-h-0">
<Dialog
title={language.t("dialog.model.select.title")}
class="overflow-y-auto [&_[data-slot=dialog-body]]:overflow-visible [&_[data-slot=dialog-body]]:flex-none"
>
<div class="flex flex-col gap-3 px-2.5">
<div class="text-14-medium text-text-base px-2.5">{language.t("dialog.model.unpaid.freeModels.title")}</div>
<List
class="flex-1 min-h-0 [&_[data-slot=list-scroll]]:flex-1 [&_[data-slot=list-scroll]]:min-h-0"
class="[&_[data-slot=list-scroll]]:overflow-visible"
ref={(ref) => (listRef = ref)}
items={local.model.list}
current={local.model.current()}
@@ -76,8 +79,6 @@ export const DialogSelectModelUnpaid: Component = () => {
</div>
)}
</List>
<div />
<div />
</div>
<div class="px-1.5 pb-1.5">
<div class="w-full rounded-sm border border-border-weak-base bg-surface-raised-base">

View File

@@ -1953,6 +1953,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
keybind={command.keybind("model.variant.cycle")}
>
<Button
data-action="model-variant-cycle"
variant="ghost"
class="text-text-base _hidden group-hover/prompt-input:inline-block capitalize text-12-regular"
onClick={() => local.model.variant.cycle()}

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-app",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"type": "module",
"license": "MIT",
"scripts": {

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/console-core",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"private": true,
"type": "module",
"license": "MIT",

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-function",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-mail",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",

View File

@@ -0,0 +1,38 @@
# CI containers
Prebuilt images intended to speed up GitHub Actions jobs by baking in
large, slow-to-install dependencies. These are designed for Linux jobs
that can use `job.container` in workflows.
Images
- `base`: Ubuntu 24.04 with common build tools and utilities
- `bun-node`: `base` plus Bun and Node.js 24
- `rust`: `bun-node` plus Rust (stable, minimal profile)
- `tauri-linux`: `rust` plus Tauri Linux build dependencies
- `publish`: `bun-node` plus Docker CLI and AUR tooling
Build
```
REGISTRY=ghcr.io/anomalyco TAG=24.04 bun ./packages/containers/script/build.ts
REGISTRY=ghcr.io/anomalyco TAG=24.04 bun ./packages/containers/script/build.ts --push
```
Workflow usage
```
jobs:
build-cli:
runs-on: ubuntu-latest
container:
image: ghcr.io/anomalyco/build/bun-node:24.04
```
Notes
- These images only help Linux jobs. macOS and Windows jobs cannot run
inside Linux containers.
- `--push` publishes multi-arch (amd64 + arm64) images using Buildx.
- If a job uses Docker Buildx, the container needs access to the host
Docker daemon (or `docker-in-docker` with privileged mode).

View File

@@ -0,0 +1,18 @@
FROM ubuntu:24.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
curl \
git \
jq \
openssh-client \
pkg-config \
python3 \
unzip \
xz-utils \
zip \
&& rm -rf /var/lib/apt/lists/*

View File

@@ -0,0 +1,24 @@
ARG REGISTRY=ghcr.io/anomalyco
FROM ${REGISTRY}/build/base:24.04
SHELL ["/bin/bash", "-lc"]
ARG NODE_VERSION=24.4.0
ARG BUN_VERSION=1.3.5
ENV BUN_INSTALL=/opt/bun
ENV PATH=/opt/bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
RUN set -euo pipefail; \
arch=$(uname -m); \
node_arch=x64; \
if [ "$arch" = "aarch64" ]; then node_arch=arm64; fi; \
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
| tar -xJf - -C /usr/local --strip-components=1; \
corepack enable
RUN set -euo pipefail; \
curl -fsSL https://bun.sh/install | bash -s -- "bun-v${BUN_VERSION}"; \
bun --version; \
node --version; \
npm --version

View File

@@ -0,0 +1,10 @@
ARG REGISTRY=ghcr.io/anomalyco
FROM ${REGISTRY}/build/bun-node:24.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
docker.io \
pacman-package-manager \
&& rm -rf /var/lib/apt/lists/*

View File

@@ -0,0 +1,13 @@
ARG REGISTRY=ghcr.io/anomalyco
FROM ${REGISTRY}/build/bun-node:24.04
ARG RUST_TOOLCHAIN=stable
ENV CARGO_HOME=/opt/cargo
ENV RUSTUP_HOME=/opt/rustup
ENV PATH=/opt/cargo/bin:/opt/bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
RUN set -euo pipefail; \
curl -fsSL https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain "${RUST_TOOLCHAIN}"; \
rustc --version; \
cargo --version

View File

@@ -0,0 +1,77 @@
#!/usr/bin/env bun
import { $ } from "bun"
import path from "path"
import { fileURLToPath } from "url"
const rootDir = fileURLToPath(new URL("../../..", import.meta.url))
process.chdir(rootDir)
const reg = process.env.REGISTRY ?? "ghcr.io/anomalyco"
const tag = process.env.TAG ?? "24.04"
const push = process.argv.includes("--push") || process.env.PUSH === "1"
const root = path.join(rootDir, "package.json")
const pkg = await Bun.file(root).json()
const manager = pkg.packageManager ?? ""
const bun = manager.startsWith("bun@") ? manager.slice(4) : ""
if (!bun) throw new Error("packageManager must be bun@<version>")
const images = ["base", "bun-node", "rust", "tauri-linux", "publish"]
const setup = async () => {
if (!push) return
const list = await $`docker buildx ls`.text()
if (list.includes("opencode")) {
await $`docker buildx use opencode`
return
}
await $`docker buildx create --name opencode --use`
}
await setup()
const platform = "linux/amd64,linux/arm64"
for (const name of images) {
const image = `${reg}/build/${name}:${tag}`
const file = `packages/containers/${name}/Dockerfile`
if (name === "base") {
if (push) {
console.log(`docker buildx build --platform ${platform} -f ${file} -t ${image} --push .`)
await $`docker buildx build --platform ${platform} -f ${file} -t ${image} --push .`
}
if (!push) {
console.log(`docker build -f ${file} -t ${image} .`)
await $`docker build -f ${file} -t ${image} .`
}
}
if (name === "bun-node") {
if (push) {
console.log(
`docker buildx build --platform ${platform} -f ${file} -t ${image} --build-arg REGISTRY=${reg} --build-arg BUN_VERSION=${bun} --push .`,
)
await $`docker buildx build --platform ${platform} -f ${file} -t ${image} --build-arg REGISTRY=${reg} --build-arg BUN_VERSION=${bun} --push .`
}
if (!push) {
console.log(`docker build -f ${file} -t ${image} --build-arg REGISTRY=${reg} --build-arg BUN_VERSION=${bun} .`)
await $`docker build -f ${file} -t ${image} --build-arg REGISTRY=${reg} --build-arg BUN_VERSION=${bun} .`
}
}
if (name !== "base" && name !== "bun-node") {
if (push) {
console.log(
`docker buildx build --platform ${platform} -f ${file} -t ${image} --build-arg REGISTRY=${reg} --push .`,
)
await $`docker buildx build --platform ${platform} -f ${file} -t ${image} --build-arg REGISTRY=${reg} --push .`
}
if (!push) {
console.log(`docker build -f ${file} -t ${image} --build-arg REGISTRY=${reg} .`)
await $`docker build -f ${file} -t ${image} --build-arg REGISTRY=${reg} .`
}
}
if (push) {
console.log(`pushed ${image}`)
}
}

View File

@@ -0,0 +1,12 @@
ARG REGISTRY=ghcr.io/anomalyco
FROM ${REGISTRY}/build/rust:24.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libappindicator3-dev \
libwebkit2gtk-4.1-dev \
librsvg2-dev \
patchelf \
&& rm -rf /var/lib/apt/lists/*

View File

@@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/bun/tsconfig.json",
"compilerOptions": {
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"noUncheckedIndexedAccess": false
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "@opencode-ai/desktop",
"private": true,
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"type": "module",
"license": "MIT",
"scripts": {

View File

@@ -1,8 +1,14 @@
#!/usr/bin/env bun
import { $ } from "bun"
import { Script } from "@opencode-ai/script"
import { copyBinaryToSidecarFolder, getCurrentSidecar, windowsify } from "./utils"
const pkg = await Bun.file("./package.json").json()
pkg.version = Script.version
await Bun.write("./package.json", JSON.stringify(pkg, null, 2) + "\n")
console.log(`Updated package.json version to ${Script.version}`)
const sidecarConfig = getCurrentSidecar()
const dir = "src-tauri/target/opencode-binaries"

View File

@@ -4914,9 +4914,9 @@ dependencies = [
[[package]]
name = "tauri-plugin-fs"
version = "2.4.4"
version = "2.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47df422695255ecbe7bac7012440eddaeefd026656171eac9559f5243d3230d9"
checksum = "ed390cc669f937afeb8b28032ce837bac8ea023d975a2e207375ec05afaf1804"
dependencies = [
"anyhow",
"dunce",
@@ -4936,9 +4936,9 @@ dependencies = [
[[package]]
name = "tauri-plugin-http"
version = "2.5.4"
version = "2.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00685aceab12643cf024f712ab0448ba8fcadf86f2391d49d2e5aa732aacc70"
checksum = "68bef611ccbfbce67c813959c11b23c1c084d201aa94222de9eba5f9edc3f897"
dependencies = [
"bytes",
"cookie_store",

View File

@@ -28,7 +28,7 @@ tauri-plugin-process = "2"
tauri-plugin-store = "2"
tauri-plugin-window-state = "2"
tauri-plugin-clipboard-manager = "2"
tauri-plugin-http = "2"
tauri-plugin-http = "2.5.6"
tauri-plugin-notification = "2"
tauri-plugin-single-instance = { version = "2", features = ["deep-link"] }

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/enterprise",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"private": true,
"type": "module",
"license": "MIT",

View File

@@ -1,7 +1,7 @@
id = "opencode"
name = "OpenCode"
description = "The open source coding agent."
version = "0.0.0-ci-202601291718"
version = "1.1.45"
schema_version = 1
authors = ["Anomaly"]
repository = "https://github.com/anomalyco/opencode"
@@ -11,26 +11,26 @@ name = "OpenCode"
icon = "./icons/opencode.svg"
[agent_servers.opencode.targets.darwin-aarch64]
archive = "https://github.com/anomalyco/opencode/releases/download/v0.0.0-ci-202601291718/opencode-darwin-arm64.zip"
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.45/opencode-darwin-arm64.zip"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.darwin-x86_64]
archive = "https://github.com/anomalyco/opencode/releases/download/v0.0.0-ci-202601291718/opencode-darwin-x64.zip"
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.45/opencode-darwin-x64.zip"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.linux-aarch64]
archive = "https://github.com/anomalyco/opencode/releases/download/v0.0.0-ci-202601291718/opencode-linux-arm64.tar.gz"
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.45/opencode-linux-arm64.tar.gz"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.linux-x86_64]
archive = "https://github.com/anomalyco/opencode/releases/download/v0.0.0-ci-202601291718/opencode-linux-x64.tar.gz"
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.45/opencode-linux-x64.tar.gz"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.windows-x86_64]
archive = "https://github.com/anomalyco/opencode/releases/download/v0.0.0-ci-202601291718/opencode-windows-x64.zip"
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.45/opencode-windows-x64.zip"
cmd = "./opencode.exe"
args = ["acp"]

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/function",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",

View File

@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"name": "opencode",
"type": "module",
"license": "MIT",

View File

@@ -32,6 +32,21 @@ import { Event } from "../server/event"
export namespace Config {
const log = Log.create({ service: "config" })
// Managed settings directory for enterprise deployments (highest priority, admin-controlled)
// These settings override all user and project settings
function getManagedConfigDir(): string {
switch (process.platform) {
case "darwin":
return "/Library/Application Support/opencode"
case "win32":
return path.join(process.env.ProgramData || "C:\\ProgramData", "opencode")
default:
return "/etc/opencode"
}
}
const managedConfigDir = process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR || getManagedConfigDir()
// Custom merge function that concatenates array fields instead of replacing them
function mergeConfigConcatArrays(target: Info, source: Info): Info {
const merged = mergeDeep(target, source)
@@ -148,8 +163,18 @@ export namespace Config {
result.plugin.push(...(await loadPlugin(dir)))
}
// Load managed config files last (highest priority) - enterprise admin-controlled
// Kept separate from directories array to avoid write operations when installing plugins
// which would fail on system directories requiring elevated permissions
// This way it only loads config file and not skills/plugins/commands
if (existsSync(managedConfigDir)) {
for (const file of ["opencode.jsonc", "opencode.json"]) {
result = mergeConfigConcatArrays(result, await loadFile(path.join(managedConfigDir, file)))
}
}
// Migrate deprecated mode field to agent field
for (const [name, mode] of Object.entries(result.mode)) {
for (const [name, mode] of Object.entries(result.mode ?? {})) {
result.agent = mergeDeep(result.agent ?? {}, {
[name]: {
...mode,

View File

@@ -1,4 +1,3 @@
import os from "os"
import { Installation } from "@/installation"
import { Provider } from "@/provider/provider"
import { Log } from "@/util/log"
@@ -9,7 +8,6 @@ import {
type StreamTextResult,
type Tool,
type ToolSet,
extractReasoningMiddleware,
tool,
jsonSchema,
} from "ai"
@@ -261,7 +259,6 @@ export namespace LLM {
return args.params
},
},
extractReasoningMiddleware({ tagName: "think", startWithReasoning: false }),
],
}),
experimental_telemetry: {

View File

@@ -1,4 +1,4 @@
import { test, expect, describe, mock } from "bun:test"
import { test, expect, describe, mock, afterEach } from "bun:test"
import { Config } from "../../src/config/config"
import { Instance } from "../../src/project/instance"
import { Auth } from "../../src/auth"
@@ -6,6 +6,23 @@ import { tmpdir } from "../fixture/fixture"
import path from "path"
import fs from "fs/promises"
import { pathToFileURL } from "url"
import { Global } from "../../src/global"
// Get managed config directory from environment (set in preload.ts)
const managedConfigDir = process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR!
afterEach(async () => {
await fs.rm(managedConfigDir, { force: true, recursive: true }).catch(() => {})
})
async function writeManagedSettings(settings: object, filename = "opencode.json") {
await fs.mkdir(managedConfigDir, { recursive: true })
await Bun.write(path.join(managedConfigDir, filename), JSON.stringify(settings))
}
async function writeConfig(dir: string, config: object, name = "opencode.json") {
await Bun.write(path.join(dir, name), JSON.stringify(config))
}
test("loads config with defaults when no files exist", async () => {
await using tmp = await tmpdir()
@@ -21,14 +38,11 @@ test("loads config with defaults when no files exist", async () => {
test("loads JSON config file", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
model: "test/model",
username: "testuser",
}),
)
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
model: "test/model",
username: "testuser",
})
},
})
await Instance.provide({
@@ -68,21 +82,19 @@ test("loads JSONC config file", async () => {
test("merges multiple config files with correct precedence", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(
path.join(dir, "opencode.jsonc"),
JSON.stringify({
await writeConfig(
dir,
{
$schema: "https://opencode.ai/config.json",
model: "base",
username: "base",
}),
)
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
model: "override",
}),
},
"opencode.jsonc",
)
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
model: "override",
})
},
})
await Instance.provide({
@@ -102,13 +114,10 @@ test("handles environment variable substitution", async () => {
try {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
theme: "{env:TEST_VAR}",
}),
)
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
theme: "{env:TEST_VAR}",
})
},
})
await Instance.provide({
@@ -169,13 +178,10 @@ test("handles file inclusion substitution", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(path.join(dir, "included.txt"), "test_theme")
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
theme: "{file:included.txt}",
}),
)
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
theme: "{file:included.txt}",
})
},
})
await Instance.provide({
@@ -190,13 +196,10 @@ test("handles file inclusion substitution", async () => {
test("validates config schema and throws on invalid fields", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
invalid_field: "should cause error",
}),
)
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
invalid_field: "should cause error",
})
},
})
await Instance.provide({
@@ -225,19 +228,16 @@ test("throws error for invalid JSON", async () => {
test("handles agent configuration", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
agent: {
test_agent: {
model: "test/model",
temperature: 0.7,
description: "test agent",
},
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
agent: {
test_agent: {
model: "test/model",
temperature: 0.7,
description: "test agent",
},
}),
)
},
})
},
})
await Instance.provide({
@@ -258,19 +258,16 @@ test("handles agent configuration", async () => {
test("handles command configuration", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
command: {
test_command: {
template: "test template",
description: "test command",
agent: "test_agent",
},
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
command: {
test_command: {
template: "test template",
description: "test command",
agent: "test_agent",
},
}),
)
},
})
},
})
await Instance.provide({
@@ -894,6 +891,86 @@ test("migrates legacy write tool to edit permission", async () => {
})
})
// Managed settings tests
// Note: preload.ts sets OPENCODE_TEST_MANAGED_CONFIG which Global.Path.managedConfig uses
test("managed settings override user settings", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
model: "user/model",
share: "auto",
username: "testuser",
})
},
})
await writeManagedSettings({
$schema: "https://opencode.ai/config.json",
model: "managed/model",
share: "disabled",
})
await Instance.provide({
directory: tmp.path,
fn: async () => {
const config = await Config.get()
expect(config.model).toBe("managed/model")
expect(config.share).toBe("disabled")
expect(config.username).toBe("testuser")
},
})
})
test("managed settings override project settings", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
autoupdate: true,
disabled_providers: [],
theme: "dark",
})
},
})
await writeManagedSettings({
$schema: "https://opencode.ai/config.json",
autoupdate: false,
disabled_providers: ["openai"],
})
await Instance.provide({
directory: tmp.path,
fn: async () => {
const config = await Config.get()
expect(config.autoupdate).toBe(false)
expect(config.disabled_providers).toEqual(["openai"])
expect(config.theme).toBe("dark")
},
})
})
test("missing managed settings file is not an error", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await writeConfig(dir, {
$schema: "https://opencode.ai/config.json",
model: "user/model",
})
},
})
await Instance.provide({
directory: tmp.path,
fn: async () => {
const config = await Config.get()
expect(config.model).toBe("user/model")
},
})
})
test("migrates legacy edit tool to edit permission", async () => {
await using tmp = await tmpdir({
init: async (dir) => {

View File

@@ -17,6 +17,10 @@ const testHome = path.join(dir, "home")
await fs.mkdir(testHome, { recursive: true })
process.env["OPENCODE_TEST_HOME"] = testHome
// Set test managed config directory to isolate tests from system managed settings
const testManagedConfigDir = path.join(dir, "managed")
process.env["OPENCODE_TEST_MANAGED_CONFIG_DIR"] = testManagedConfigDir
process.env["XDG_DATA_HOME"] = path.join(dir, "share")
process.env["XDG_CACHE_HOME"] = path.join(dir, "cache")
process.env["XDG_CONFIG_HOME"] = path.join(dir, "config")

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/plugin",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"type": "module",
"license": "MIT",
"scripts": {

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/sdk",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"type": "module",
"license": "MIT",
"scripts": {

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/slack",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"type": "module",
"license": "MIT",
"scripts": {

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/ui",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"type": "module",
"license": "MIT",
"exports": {

View File

@@ -28,18 +28,33 @@ const Context = createContext<ReturnType<typeof init>>()
function init() {
const [active, setActive] = createSignal<Active | undefined>()
let closing = false
const timer = { current: undefined as ReturnType<typeof setTimeout> | undefined }
const lock = { value: false }
onCleanup(() => {
if (timer.current === undefined) return
clearTimeout(timer.current)
timer.current = undefined
})
const close = () => {
const current = active()
if (!current || closing) return
closing = true
if (!current || lock.value) return
lock.value = true
current.onClose?.()
current.setClosing(true)
setTimeout(() => {
const id = current.id
if (timer.current !== undefined) {
clearTimeout(timer.current)
timer.current = undefined
}
timer.current = setTimeout(() => {
timer.current = undefined
current.dispose()
setActive(undefined)
closing = false
if (active()?.id === id) setActive(undefined)
lock.value = false
}, 100)
}
@@ -64,7 +79,12 @@ function init() {
current.dispose()
setActive(undefined)
}
closing = false
if (timer.current !== undefined) {
clearTimeout(timer.current)
timer.current = undefined
}
lock.value = false
const id = Math.random().toString(36).slice(2)
let dispose: (() => void) | undefined

View File

@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/util",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"private": true,
"type": "module",
"license": "MIT",

View File

@@ -2,7 +2,7 @@
"name": "@opencode-ai/web",
"type": "module",
"license": "MIT",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"scripts": {
"dev": "astro dev",
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",

View File

@@ -41,6 +41,7 @@ async function main() {
for (const pr of prs) {
console.log(`\nProcessing PR #${pr.number}: ${pr.title}`)
// Fetch the PR
const fetchPR = await $`git fetch origin pull/${pr.number}/head:pr-${pr.number}`.nothrow()
if (fetchPR.exitCode !== 0) {
console.log(` Failed to fetch PR #${pr.number}, skipping`)
@@ -48,6 +49,24 @@ async function main() {
continue
}
// Try to rebase onto current beta branch
console.log(` Attempting to rebase PR #${pr.number}...`)
const rebase = await $`git rebase beta pr-${pr.number}`.nothrow()
if (rebase.exitCode !== 0) {
console.log(` Rebase failed for PR #${pr.number} (has conflicts)`)
await $`git rebase --abort`.nothrow()
await $`git checkout beta`.nothrow()
skipped.push({ number: pr.number, reason: "Rebase failed (conflicts)" })
continue
}
// Move rebased commits to pr-${pr.number} branch and checkout back to beta
await $`git checkout -B pr-${pr.number}`.nothrow()
await $`git checkout beta`.nothrow()
console.log(` Successfully rebased PR #${pr.number}`)
// Now squash merge the rebased PR
const merge = await $`git merge --squash pr-${pr.number}`.nothrow()
if (merge.exitCode !== 0) {
console.log(` Squash merge failed for PR #${pr.number}`)

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bun
import { $ } from "bun"
import { createOpencode } from "@opencode-ai/sdk"
import { createOpencode } from "@opencode-ai/sdk/v2"
import { parseArgs } from "util"
export const team = [
@@ -18,13 +18,29 @@ export const team = [
"R44VC0RP",
]
export async function getLatestRelease() {
return fetch("https://api.github.com/repos/anomalyco/opencode/releases/latest")
.then((res) => {
if (!res.ok) throw new Error(res.statusText)
return res.json()
})
.then((data: any) => data.tag_name.replace(/^v/, ""))
type Release = {
tag_name: string
draft: boolean
prerelease: boolean
}
export async function getLatestRelease(skip?: string) {
const data = await fetch("https://api.github.com/repos/anomalyco/opencode/releases?per_page=100").then((res) => {
if (!res.ok) throw new Error(res.statusText)
return res.json()
})
const releases = data as Release[]
const target = skip?.replace(/^v/, "")
for (const release of releases) {
if (release.draft) continue
const tag = release.tag_name.replace(/^v/, "")
if (target && tag === target) continue
return tag
}
throw new Error("No releases found")
}
type Commit = {
@@ -137,9 +153,9 @@ async function summarizeCommit(opencode: Awaited<ReturnType<typeof createOpencod
console.log("summarizing commit:", message)
const session = await opencode.client.session.create()
const result = await opencode.client.session
.prompt({
path: { id: session.data!.id },
body: {
.prompt(
{
sessionID: session.data!.id,
model: { providerID: "opencode", modelID: "claude-sonnet-4-5" },
tools: {
"*": false,
@@ -153,8 +169,10 @@ Commit: ${message}`,
},
],
},
signal: AbortSignal.timeout(120_000),
})
{
signal: AbortSignal.timeout(120_000),
},
)
.then((x) => x.data?.parts?.find((y) => y.type === "text")?.text ?? message)
return result.trim()
}
@@ -222,7 +240,7 @@ export async function buildNotes(from: string, to: string) {
console.log("generating changelog since " + from)
const opencode = await createOpencode({ port: 5044 })
const opencode = await createOpencode({ port: 0 })
const notes: string[] = []
try {
@@ -242,8 +260,9 @@ export async function buildNotes(from: string, to: string) {
throw error
}
} finally {
opencode.server.close()
await opencode.server.close()
}
console.log("changelog generation complete")
const contributors = await getContributors(from, to)

View File

@@ -2,7 +2,6 @@
import { $ } from "bun"
import { Script } from "@opencode-ai/script"
import { buildNotes, getLatestRelease } from "./changelog"
const highlightsTemplate = `
<!--
@@ -58,16 +57,12 @@ await $`bun install`
await import(`../packages/sdk/js/script/build.ts`)
if (Script.release) {
const previous = await getLatestRelease()
const notes = await buildNotes(previous, "HEAD")
// notes.unshift(highlightsTemplate)
await $`git commit -am "release: v${Script.version}"`
await $`git tag v${Script.version}`
await $`git fetch origin`
await $`git cherry-pick HEAD..origin/dev`.nothrow()
await $`git push origin HEAD --tags --no-verify --force-with-lease`
await new Promise((resolve) => setTimeout(resolve, 5_000))
await $`gh release edit v${Script.version} --draft=false --title "v${Script.version}" --notes ${notes.join("\n") || "No notable changes"}`
}
console.log("\n=== cli ===\n")

View File

@@ -2,11 +2,18 @@
import { Script } from "@opencode-ai/script"
import { $ } from "bun"
import { buildNotes, getLatestRelease } from "./changelog"
let output = [`version=${Script.version}`]
const output = [`version=${Script.version}`]
if (!Script.preview) {
await $`gh release create v${Script.version} -d --title "v${Script.version}" ${Script.preview ? "--prerelease" : ""}`
const previous = await getLatestRelease()
const notes = await buildNotes(previous, "HEAD")
const body = notes.join("\n") || "No notable changes"
const dir = process.env.RUNNER_TEMP ?? "/tmp"
const file = `${dir}/opencode-release-notes.txt`
await Bun.write(file, body)
await $`gh release create v${Script.version} -d --title "v${Script.version}" --notes-file ${file}`
const release = await $`gh release view v${Script.version} --json id,tagName`.json()
output.push(`release=${release.id}`)
output.push(`tag=${release.tagName}`)
@@ -15,3 +22,5 @@ if (!Script.preview) {
if (process.env.GITHUB_OUTPUT) {
await Bun.write(process.env.GITHUB_OUTPUT, output.join("\n"))
}
process.exit(0)

View File

@@ -2,7 +2,7 @@
"name": "opencode",
"displayName": "opencode",
"description": "opencode for VS Code",
"version": "0.0.0-ci-202601291718",
"version": "1.1.45",
"publisher": "sst-dev",
"repository": {
"type": "git",