Compare commits

...

4 Commits

Author SHA1 Message Date
Simon Klee 6fbfd8e229 build: bump opentui to 0.4.5
Embed the tree-sitter worker via import.meta.resolve so the
binary build no longer depends on node_modules layout.
2026-07-18 08:21:04 +02:00
opencode-agent[bot] 901c9e7329 fix(app): disable unavailable file navigation (#37595)
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
2026-07-18 15:39:15 +10:00
opencode-agent[bot] 3476e6baa5 chore: update nix node_modules hashes 2026-07-18 03:05:17 +00:00
opencode-agent[bot] 86e04d4174 revert(tui): downgrade opentui to 0.4.3 (#37582)
Co-authored-by: Aiden Cline <rekram1-node@users.noreply.github.com>
2026-07-17 21:51:48 -05:00
5 changed files with 33 additions and 42 deletions
+4 -4
View File
@@ -1,8 +1,8 @@
{
"nodeModules": {
"x86_64-linux": "sha256-zAftZieWR0hWQQVkhEa826iueHaRnKxtyRodhNb+Apc=",
"aarch64-linux": "sha256-cTG+gB7CuiFgaYHSFbzXaXUI1C2kiugV3B9rUDRUwlg=",
"aarch64-darwin": "sha256-ap4Xv5ZliourkI4mcD0ktbzSI88jb4oVBv5mMK3WdUs=",
"x86_64-darwin": "sha256-NGRJMMnaMNrf3FkcYwr5PcfVm5thhlNLGIeMmAK0MeE="
"x86_64-linux": "sha256-XWoSYsV18a5uvjM3KuyGQWiFAtcCV0ij8brOLuFOW+g=",
"aarch64-linux": "sha256-50cI0CuzzMRO8vznPxTHRhgHirE7siOg6AmyKLhZ2oo=",
"aarch64-darwin": "sha256-5JpSBNyKqiB+gOrkxMNWyWGWLdNlbEiirA56GDhAS4E=",
"x86_64-darwin": "sha256-X1r9aOSEdMUqWtqa4a/tBK2nRSwIWfKOwqJfpFknhII="
}
}
+1 -10
View File
@@ -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"
@@ -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,
@@ -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"],
@@ -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") } : {}),
},
})
+13 -10
View File
@@ -1,7 +1,6 @@
#!/usr/bin/env bun
import { $ } from "bun"
import fs from "fs"
import path from "path"
import { fileURLToPath } from "url"
import { createSolidTransformPlugin } from "@opentui/solid/bun-plugin"
@@ -49,6 +48,7 @@ const createEmbeddedWebUIBundle = async () => {
}
const embeddedFileMap = skipEmbedWebUi ? null : await createEmbeddedWebUIBundle()
const treeSitterWorker = await Bun.file(fileURLToPath(import.meta.resolve("@opentui/core/parser.worker"))).text()
const allTargets: {
os: string
@@ -156,14 +156,9 @@ for (const item of targets) {
console.log(`building ${name}`)
await $`mkdir -p dist/${name}/bin`
const localPath = path.resolve(dir, "node_modules/@opentui/core/parser.worker.js")
const rootPath = path.resolve(dir, "../../node_modules/@opentui/core/parser.worker.js")
const parserWorker = fs.realpathSync(fs.existsSync(localPath) ? localPath : rootPath)
const workerPath = "./src/cli/tui/worker.ts"
// Use platform-specific bunfs root path based on target OS
const treeSitterWorkerPath = "opentui-tree-sitter-worker.js"
const bunfsRoot = item.os === "win32" ? "B:/~BUN/root/" : "/$bunfs/root/"
const workerRelativePath = path.relative(dir, parserWorker).replaceAll("\\", "/")
await Bun.build({
conditions: ["bun", "node"],
@@ -184,13 +179,21 @@ for (const item of targets) {
execArgv: [`--user-agent=opencode/${Script.version}`, "--use-system-ca", "--"],
windows: {},
},
files: embeddedFileMap ? { "opencode-web-ui.gen.ts": embeddedFileMap } : {},
entrypoints: ["./src/index.ts", parserWorker, workerPath, ...(embeddedFileMap ? ["opencode-web-ui.gen.ts"] : [])],
files: {
[treeSitterWorkerPath]: treeSitterWorker,
...(embeddedFileMap ? { "opencode-web-ui.gen.ts": embeddedFileMap } : {}),
},
entrypoints: [
"./src/index.ts",
workerPath,
treeSitterWorkerPath,
...(embeddedFileMap ? ["opencode-web-ui.gen.ts"] : []),
],
define: {
FFF_LIBC: JSON.stringify(item.abi === "musl" ? "musl" : "gnu"),
OPENCODE_VERSION: `'${Script.version}'`,
OPENCODE_MODELS_DEV: generated.modelsData,
OTUI_TREE_SITTER_WORKER_PATH: bunfsRoot + workerRelativePath,
OTUI_TREE_SITTER_WORKER_PATH: bunfsRoot + treeSitterWorkerPath,
OPENCODE_WORKER_PATH: workerPath,
OPENCODE_CHANNEL: `'${Script.channel}'`,
OPENCODE_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "",
@@ -165,15 +165,11 @@ export function SessionReviewV2(props: SessionReviewV2Props) {
}
const prev = () => {
const files = props.files
if (files.length === 0) return
return files[(fileIndex() - 1 + files.length) % files.length]
return props.files[fileIndex() - 1]
}
const next = () => {
const files = props.files
if (files.length === 0) return
return files[(fileIndex() + 1) % files.length]
return props.files[fileIndex() + 1]
}
const canCycle = () => props.files.length > 0
@@ -195,8 +191,10 @@ export function SessionReviewV2(props: SessionReviewV2Props) {
const target = event.target
if (target instanceof HTMLElement && (target.isContentEditable || target.closest("input, textarea, select"))) return
if (!props.hasDiffs || !canCycle()) return
const file = event.key === "<" ? prev() : next()
if (!file) return
event.preventDefault()
cycle(event.key === "<" ? prev() : next())
cycle(file)
})
const toolbarStart = () => (
@@ -217,6 +215,7 @@ export function SessionReviewV2(props: SessionReviewV2Props) {
<div class="flex items-center">
<TooltipV2
openDelay={2000}
inactive={!prev()}
value={
<>
{i18n.t("ui.sessionReviewV2.previousFile")}
@@ -229,13 +228,14 @@ export function SessionReviewV2(props: SessionReviewV2Props) {
variant="ghost"
size="small"
class="session-review-v2-file-nav-button"
disabled={!canCycle()}
disabled={!prev()}
onClick={() => cycle(prev())}
aria-label={i18n.t("ui.sessionReviewV2.previousFile")}
/>
</TooltipV2>
<TooltipV2
openDelay={2000}
inactive={!next()}
value={
<>
{i18n.t("ui.sessionReviewV2.nextFile")}
@@ -248,7 +248,7 @@ export function SessionReviewV2(props: SessionReviewV2Props) {
variant="ghost"
size="small"
class="session-review-v2-file-nav-button"
disabled={!canCycle()}
disabled={!next()}
onClick={() => cycle(next())}
aria-label={i18n.t("ui.sessionReviewV2.nextFile")}
/>
+6 -9
View File
@@ -160,21 +160,18 @@ async function fixKnownLockfileIssues() {
if (stale.length === 0) return []
if (stale.some((item) => !item.entry.startsWith("opentui-spinner/@opentui/"))) return []
const lines = txt.split("\n")
const spinnerEntry = /^ "(opentui-spinner\/@opentui\/[^"]+)": \[.*\],\r?$/
const removed = lines
.map((line) => line.match(spinnerEntry)?.[1])
const removed = txt
.split("\n")
.map((line) => line.match(/^ "(opentui-spinner\/@opentui\/[^\"]+)": /)?.[1])
.filter((item): item is string => item !== undefined)
if (removed.length === 0) return []
// Bun separates package records with a blank line, so remove each record's separator with it.
await Bun.write(
lockfile,
lines
.filter(
(line, index) => !spinnerEntry.test(line) && !(line.trim() === "" && spinnerEntry.test(lines[index - 1] ?? "")),
)
txt
.split("\n")
.filter((line) => !line.match(/^ "opentui-spinner\/@opentui\//))
.join("\n"),
)
return removed