Skip to content
Merged
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
34 changes: 17 additions & 17 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions infra/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,25 @@ export const zoneID = "430ba34c138cfb5360826c4909f99be8"
export const awsStage = $app.stage === "production" ? "production" : "dev"
export const deployAws = $app.stage === awsStage

if ($app.stage === "production") {
new cloudflare.DnsRecord("TrustCenter", {
zoneId: zoneID,
name: "trust.opencode.ai",
type: "CNAME",
content: "3a69a5bb27875189.vercel-dns-016.com",
proxied: false,
ttl: 60,
})

new cloudflare.DnsRecord("TrustCenterVerification", {
zoneId: zoneID,
name: "opencode.ai",
type: "TXT",
content: "compai-domain-verification=org_6993a99c6200a2d642bb115d",
ttl: 60,
})
}

new cloudflare.RegionalHostname("RegionalHostname", {
hostname: domain,
regionKey: "us",
Expand Down
99 changes: 66 additions & 33 deletions nix/desktop.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
makeWrapper,
writableTmpDirAsHomeHook,
autoPatchelfHook,
copyDesktopItems,
makeDesktopItem,
opencode,
}:
let
Expand All @@ -27,9 +29,12 @@ stdenv.mkDerivation (finalAttrs: {
nodejs
makeWrapper
writableTmpDirAsHomeHook
] ++ lib.optionals stdenv.hostPlatform.isLinux [
]
++ lib.optionals stdenv.hostPlatform.isLinux [
autoPatchelfHook
] ++ lib.optionals stdenv.hostPlatform.isDarwin [
copyDesktopItems
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
# Ad-hoc sign the .app: --config.mac.identity=null below skips signing.
darwin.autoSignDarwinBinariesHook
];
Expand All @@ -38,20 +43,37 @@ stdenv.mkDerivation (finalAttrs: {
(lib.getLib stdenv.cc.cc)
];

desktopItems = lib.optional stdenv.hostPlatform.isLinux (makeDesktopItem {
name = "ai.opencode.desktop";
desktopName = "OpenCode";
exec = "opencode-desktop %U";
icon = "ai.opencode.desktop";
# Electron 41 derives X11 WM_CLASS from app.name.
startupWMClass = "OpenCode";
categories = [ "Development" ];
});

env = opencode.env // {
ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
};

# https://github.com/electron/electron/issues/31121
# mac builds use a .app bundle which doesnt have this issue
postPatch = lib.optionalString stdenv.isLinux ''
BASE_PATH=packages/desktop
FILES=(src/main/windows.ts)
for file in "''${FILES[@]}"; do
substituteInPlace $BASE_PATH/$file \
--replace-fail "process.resourcesPath" "'$out/opt/opencode-desktop/resources'"
done
'';
postPatch =
# NOTE: Relax Bun version check to be a warning instead of an error
''
substituteInPlace packages/script/src/index.ts \
--replace-fail 'throw new Error(`This script requires bun@''${expectedBunVersionRange}' \
'console.warn(`Warning: This script requires bun@''${expectedBunVersionRange}'
''
# https://github.com/electron/electron/issues/31121
# mac builds use a .app bundle which doesnt have this issue
+ lib.optionalString stdenv.isLinux ''
BASE_PATH=packages/desktop
FILES=(src/main/windows.ts)
for file in "''${FILES[@]}"; do
substituteInPlace $BASE_PATH/$file \
--replace-fail "process.resourcesPath" "'$out/opt/opencode-desktop/resources'"
done
'';

preBuild = ''
cp -r "${electron.dist}" $HOME/.electron-dist
Expand All @@ -76,27 +98,38 @@ stdenv.mkDerivation (finalAttrs: {
runHook postBuild
'';

installPhase =
''
runHook preInstall
''
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
mkdir -p $out/Applications
mv dist/mac*/*.app $out/Applications
makeWrapper "$out/Applications/OpenCode.app/Contents/MacOS/OpenCode" $out/bin/opencode-desktop
''
+ lib.optionalString stdenv.hostPlatform.isLinux ''
mkdir -p $out/opt/opencode-desktop
cp -r dist/linux*-unpacked/{resources,LICENSE*} $out/opt/opencode-desktop
makeWrapper ${lib.getExe electron} $out/bin/opencode-desktop \
--inherit-argv0 \
--set ELECTRON_FORCE_IS_PACKAGED 1 \
--add-flags $out/opt/opencode-desktop/resources/app.asar \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}"
''
+ ''
runHook postInstall
'';
installPhase = ''
runHook preInstall
''
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
mkdir -p $out/Applications
mv dist/mac*/*.app $out/Applications
makeWrapper "$out/Applications/OpenCode.app/Contents/MacOS/OpenCode" $out/bin/opencode-desktop
''
+ lib.optionalString stdenv.hostPlatform.isLinux ''
mkdir -p $out/opt/opencode-desktop
cp -r dist/linux*-unpacked/{resources,LICENSE*} $out/opt/opencode-desktop
install -Dm644 resources/icons/32x32.png \
"$out/share/icons/hicolor/32x32/apps/ai.opencode.desktop.png"
install -Dm644 resources/icons/64x64.png \
"$out/share/icons/hicolor/64x64/apps/ai.opencode.desktop.png"
install -Dm644 resources/icons/128x128.png \
"$out/share/icons/hicolor/128x128/apps/ai.opencode.desktop.png"
install -Dm644 resources/icons/128x128@2x.png \
"$out/share/icons/hicolor/256x256/apps/ai.opencode.desktop.png"
install -Dm644 resources/icons/icon.png \
"$out/share/icons/hicolor/512x512/apps/ai.opencode.desktop.png"
install -Dm644 resources/ai.opencode.desktop.metainfo.xml \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fix the hard-coded desktop metainfo path

For Linux Nix desktop builds, bun run build runs packages/desktop/scripts/prebuild.ts, whose copy-metainfo.ts writes resources/${identity.appId}.metainfo.xml; in this fork with OPENCODE_CHANNEL=prod that file is resources/io.github.logiclyra.opencodeclassic.metainfo.xml, not resources/ai.opencode.desktop.metainfo.xml. This hard-coded upstream path makes the install phase fail with a missing file before the Nix desktop package can be produced.

Useful? React with 👍 / 👎.

"$out/share/metainfo/ai.opencode.desktop.metainfo.xml"
makeWrapper ${lib.getExe electron} $out/bin/opencode-desktop \
--inherit-argv0 \
--set ELECTRON_FORCE_IS_PACKAGED 1 \
--add-flags $out/opt/opencode-desktop/resources/app.asar \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}"
''
+ ''
runHook postInstall
'';

autoPatchelfIgnoreMissingDeps = [
"libc.musl-x86_64.so.1"
Expand Down
8 changes: 4 additions & 4 deletions nix/hashes.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"nodeModules": {
"x86_64-linux": "sha256-XWoSYsV18a5uvjM3KuyGQWiFAtcCV0ij8brOLuFOW+g=",
"aarch64-linux": "sha256-50cI0CuzzMRO8vznPxTHRhgHirE7siOg6AmyKLhZ2oo=",
"aarch64-darwin": "sha256-5JpSBNyKqiB+gOrkxMNWyWGWLdNlbEiirA56GDhAS4E=",
"x86_64-darwin": "sha256-X1r9aOSEdMUqWtqa4a/tBK2nRSwIWfKOwqJfpFknhII="
"x86_64-linux": "sha256-zAftZieWR0hWQQVkhEa826iueHaRnKxtyRodhNb+Apc=",
"aarch64-linux": "sha256-cTG+gB7CuiFgaYHSFbzXaXUI1C2kiugV3B9rUDRUwlg=",
"aarch64-darwin": "sha256-ap4Xv5ZliourkI4mcD0ktbzSI88jb4oVBv5mMK3WdUs=",
"x86_64-darwin": "sha256-NGRJMMnaMNrf3FkcYwr5PcfVm5thhlNLGIeMmAK0MeE="
}
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
"@octokit/rest": "22.0.0",
"@hono/standard-validator": "0.2.0",
"@hono/zod-validator": "0.4.2",
"@opentui/core": "0.4.3",
"@opentui/keymap": "0.4.3",
"@opentui/solid": "0.4.3",
"@opentui/core": "0.4.5",
"@opentui/keymap": "0.4.5",
"@opentui/solid": "0.4.5",
"@tanstack/solid-virtual": "3.13.32",
"@shikijs/stream": "4.2.0",
"ulid": "3.0.1",
Expand Down
11 changes: 1 addition & 10 deletions packages/cli/script/build.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env bun

import { $ } from "bun"
import fs from "fs"
import { rm } from "fs/promises"
import path from "path"
import { Script } from "@opencode-ai/script"
Expand Down Expand Up @@ -51,10 +50,6 @@ const targets = singleFlag

if (!skipInstall) await $`bun install --os="*" --cpu="*" @opentui/core@${pkg.dependencies["@opentui/core"]}`

const localParserWorker = path.resolve(dir, "node_modules/@opentui/core/parser.worker.js")
const rootParserWorker = path.resolve(dir, "../../node_modules/@opentui/core/parser.worker.js")
const parserWorker = fs.realpathSync(fs.existsSync(localParserWorker) ? localParserWorker : rootParserWorker)

for (const item of targets) {
const target = [
binary,
Expand All @@ -68,7 +63,7 @@ for (const item of targets) {
const name = target.replace(binary, "cli")
console.log(`building ${name}`)
const result = await Bun.build({
entrypoints: ["./src/index.ts", parserWorker],
entrypoints: ["./src/index.ts"],
tsconfig: "./tsconfig.json",
plugins: [plugin],
external: ["node-gyp"],
Expand All @@ -94,10 +89,6 @@ for (const item of targets) {
OPENCODE_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "undefined",
// FFF_LIBC selects the fff native lib variant: "musl" or "gnu".
FFF_LIBC: item.os === "linux" ? `'${item.abi ?? "gnu"}'` : "undefined",
OTUI_TREE_SITTER_WORKER_PATH:
(item.os === "win32" ? '"B:/~BUN/root/' : '"/$bunfs/root/') +
path.relative(dir, parserWorker).replaceAll("\\", "/") +
'"',
...(item.os === "linux" ? { "process.env.OPENTUI_LIBC": JSON.stringify(item.abi ?? "glibc") } : {}),
},
})
Expand Down
2 changes: 1 addition & 1 deletion packages/console/app/src/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ export const dict = {
"zen.privacy.exceptionsLink": "الاستثناءات التالية",

"go.title": "OpenCode Go | نماذج برمجة منخفضة التكلفة للجميع",
"go.banner.text": "يحصل Kimi K3 على حدود استخدام مضاعفة لفترة محدودة",
"go.meta.description":
"يبدأ Go من $5 للشهر الأول، ثم $10/شهر، مع حدود طلب سخية لمدة 5 ساعات لـ Grok 4.5 وGLM-5.2 وGLM-5.1 وKimi K3 وKimi K2.7 Code وKimi K2.6 وMiMo-V2.5-Pro وMiMo-V2.5 وQwen3.7 Max وQwen3.7 Plus وQwen3.6 Plus وMiniMax M2.7 وMiniMax M3 وDeepSeek V4 Pro وDeepSeek V4 Flash.",
"go.hero.title": "نماذج برمجة منخفضة التكلفة للجميع",
Expand All @@ -270,7 +271,6 @@ export const dict = {
"go.graph.go": "Go",
"go.graph.label": "الطلبات كل 5 ساعات",
"go.graph.usageLimits": "حدود الاستخدام",
"go.graph.tick": "{{n}}x",
"go.graph.aria": "الطلبات كل 5 ساعات: {{free}} مقابل {{go}}",

"go.testimonials.brand.zen": "Zen",
Expand Down
2 changes: 1 addition & 1 deletion packages/console/app/src/i18n/br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ export const dict = {
"zen.privacy.exceptionsLink": "seguintes exceções",

"go.title": "OpenCode Go | Modelos de codificação de baixo custo para todos",
"go.banner.text": "Kimi K3 tem limites de uso 2x maiores por tempo limitado",
"go.meta.description":
"O Go começa em $5 no primeiro mês, depois $10/mês, com limites generosos de solicitação de 5 horas para Grok 4.5, GLM-5.2, GLM-5.1, Kimi K3, Kimi K2.7 Code, Kimi K2.6, MiMo-V2.5-Pro, MiMo-V2.5, Qwen3.7 Max, Qwen3.7 Plus, Qwen3.6 Plus, MiniMax M2.7, MiniMax M3, DeepSeek V4 Pro e DeepSeek V4 Flash.",
"go.hero.title": "Modelos de codificação de baixo custo para todos",
Expand All @@ -274,7 +275,6 @@ export const dict = {
"go.graph.go": "Go",
"go.graph.label": "Requisições por 5 horas",
"go.graph.usageLimits": "Limites de uso",
"go.graph.tick": "{{n}}x",
"go.graph.aria": "Requisições por 5h: {{free}} vs {{go}}",

"go.testimonials.brand.zen": "Zen",
Expand Down
2 changes: 1 addition & 1 deletion packages/console/app/src/i18n/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ export const dict = {
"zen.privacy.exceptionsLink": "følgende undtagelser",

"go.title": "OpenCode Go | Kodningsmodeller til lav pris for alle",
"go.banner.text": "Kimi K3 får fordoblet brugsgrænse i en begrænset periode",
"go.meta.description":
"Go starter ved $5 for den første måned, derefter $10/måned, med generøse 5-timers anmodningsgrænser for Grok 4.5, GLM-5.2, GLM-5.1, Kimi K3, Kimi K2.7 Code, Kimi K2.6, MiMo-V2.5-Pro, MiMo-V2.5, Qwen3.7 Max, Qwen3.7 Plus, Qwen3.6 Plus, MiniMax M2.7, MiniMax M3, DeepSeek V4 Pro og DeepSeek V4 Flash.",
"go.hero.title": "Kodningsmodeller til lav pris for alle",
Expand All @@ -272,7 +273,6 @@ export const dict = {
"go.graph.go": "Go",
"go.graph.label": "Forespørgsler pr. 5 timer",
"go.graph.usageLimits": "Brugsgrænser",
"go.graph.tick": "{{n}}x",
"go.graph.aria": "Forespørgsler pr. 5t: {{free}} vs {{go}}",

"go.testimonials.brand.zen": "Zen",
Expand Down
2 changes: 1 addition & 1 deletion packages/console/app/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ export const dict = {
"zen.privacy.exceptionsLink": "folgenden Ausnahmen",

"go.title": "OpenCode Go | Kostengünstige Coding-Modelle für alle",
"go.banner.text": "Kimi K3 erhält für begrenzte Zeit 2x Nutzungslimits",
"go.meta.description":
"Go beginnt bei $5 für den ersten Monat, danach $10/Monat, mit großzügigen 5-Stunden-Anfragelimits für Grok 4.5, GLM-5.2, GLM-5.1, Kimi K3, Kimi K2.7 Code, Kimi K2.6, MiMo-V2.5-Pro, MiMo-V2.5, Qwen3.7 Max, Qwen3.7 Plus, Qwen3.6 Plus, MiniMax M2.7, MiniMax M3, DeepSeek V4 Pro und DeepSeek V4 Flash.",
"go.hero.title": "Kostengünstige Coding-Modelle für alle",
Expand All @@ -274,7 +275,6 @@ export const dict = {
"go.graph.go": "Go",
"go.graph.label": "Anfragen pro 5 Stunden",
"go.graph.usageLimits": "Nutzungslimits",
"go.graph.tick": "{{n}}x",
"go.graph.aria": "Anfragen pro 5h: {{free}} vs {{go}}",

"go.testimonials.brand.zen": "Zen",
Expand Down
Loading
Loading