diff --git a/.github/actions/setup-bun/action.yml b/.github/actions/setup-bun/action.yml index cba04facce..7584334a7b 100644 --- a/.github/actions/setup-bun/action.yml +++ b/.github/actions/setup-bun/action.yml @@ -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 diff --git a/.github/actions/setup-git-committer/action.yml b/.github/actions/setup-git-committer/action.yml new file mode 100644 index 0000000000..e5a5720652 --- /dev/null +++ b/.github/actions/setup-git-committer/action.yml @@ -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 diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index d92133ea6a..f7180ea1ee 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -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 diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml new file mode 100644 index 0000000000..c7df066d41 --- /dev/null +++ b/.github/workflows/containers.yml @@ -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 }} diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index cbbab479e1..3bb8f364d6 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -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 "" diff --git a/.github/workflows/nix-hashes.yml b/.github/workflows/nix-hashes.yml index 63ab561887..061b4ada8d 100644 --- a/.github/workflows/nix-hashes.yml +++ b/.github/workflows/nix-hashes.yml @@ -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 }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index caa9aca310..3974d23ffc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -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 diff --git a/AGENTS.md b/AGENTS.md index 0769523011..85b5e67631 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,10 +1,7 @@ -# Agent Instructions - -## Quick Reference - -- Default branch: `dev` -- Regenerate JS SDK: `./packages/sdk/js/script/build.ts` -- Always use parallel tools when applicable +- 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 diff --git a/bun.lock b/bun.lock index 9cbd070090..b9145be812 100644 --- a/bun.lock +++ b/bun.lock @@ -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", }, @@ -365,7 +365,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "0.0.0-ci-202601291718", + "version": "1.1.45", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -385,7 +385,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:", @@ -396,7 +396,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", @@ -409,7 +409,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:*", @@ -451,7 +451,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "0.0.0-ci-202601291718", + "version": "1.1.45", "dependencies": { "zod": "catalog:", }, @@ -462,7 +462,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", diff --git a/nix/hashes.json b/nix/hashes.json index 10320c4684..f50c7a23df 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-Xin761tN/BqAqmICQQXS9tdrc6PuHm8L5h6RcrFQdxY=", - "aarch64-linux": "sha256-Q3aNOeF3MLY+UY8wRM16DmrbRC7R4xQvcty41M/OSMY=", - "aarch64-darwin": "sha256-okAB6LfrRa9Vj98JqwxQApKJ4b0xcLSW0hmD8j234YU=", - "x86_64-darwin": "sha256-vJXxSIk9UTCVduDAvFkgBcGa6rMbY3MJDI4YBCEFAqw=" + "x86_64-linux": "sha256-gUWzUsk81miIrjg0fZQmsIQG4pZYmEHgzN6BaXI+lfc=", + "aarch64-linux": "sha256-gwEG75ha/ojTO2iAObTmLTtEkXIXJ7BThzfI5CqlJh8=", + "aarch64-darwin": "sha256-20RGG2GkUItCzD67gDdoSLfexttM8abS//FKO9bfjoM=", + "x86_64-darwin": "sha256-i2VawFuR1UbjPVYoybU6aJDJfFo0tcvtl1aM31Y2mTQ=" } } diff --git a/packages/app/e2e/thinking-level.spec.ts b/packages/app/e2e/thinking-level.spec.ts new file mode 100644 index 0000000000..564ef3c1f3 --- /dev/null +++ b/packages/app/e2e/thinking-level.spec.ts @@ -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) +}) diff --git a/packages/app/e2e/utils.ts b/packages/app/e2e/utils.ts index eb0395950a..3de488bd9c 100644 --- a/packages/app/e2e/utils.ts +++ b/packages/app/e2e/utils.ts @@ -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 }) diff --git a/packages/app/package.json b/packages/app/package.json index 61e7edcd16..8459172e7c 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "0.0.0-ci-202601291718", + "version": "1.1.45", "description": "", "type": "module", "exports": { diff --git a/packages/app/src/components/dialog-select-model-unpaid.tsx b/packages/app/src/components/dialog-select-model-unpaid.tsx index 089c4c0cd7..78c169777e 100644 --- a/packages/app/src/components/dialog-select-model-unpaid.tsx +++ b/packages/app/src/components/dialog-select-model-unpaid.tsx @@ -34,11 +34,14 @@ export const DialogSelectModelUnpaid: Component = () => { }) return ( - -
+ +
{language.t("dialog.model.unpaid.freeModels.title")}
(listRef = ref)} items={local.model.list} current={local.model.current()} @@ -76,8 +79,6 @@ export const DialogSelectModelUnpaid: Component = () => {
)} -
-
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 4d227f44b6..5c1d417eb0 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -1953,6 +1953,7 @@ export const PromptInput: Component = (props) => { keybind={command.keybind("model.variant.cycle")} >