Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
cf5dd5a
fix(termux): add Android artifact support
wallentx Jul 6, 2026
88bc498
fix(termux): make target fork friendly
wallentx Jul 6, 2026
728e86b
chore: generate
opencode-agent[bot] Jul 6, 2026
203885d
sync release versions for v1.17.14
Jul 6, 2026
c3b9c9d
feat(data): improved model usage section
adamdotdevin Jul 6, 2026
fc09646
fix(data): refine model trend charts
adamdotdevin Jul 6, 2026
dba0801
chore: generate
opencode-agent[bot] Jul 6, 2026
26885e7
feat(app): align cmd k menu with v2 styles (#35152)
arvsrn Jul 7, 2026
254a481
fix(config): handle unavailable config directories (#35632)
jlongster Jul 7, 2026
6aff2ee
feat(app): visual improvements (#35134)
arvsrn Jul 7, 2026
9353559
chore: generate
opencode-agent[bot] Jul 7, 2026
2a08f8f
feat(app): reintroduce model context tooltip in model selector (#35087)
arvsrn Jul 7, 2026
0497e8b
chore: generate
opencode-agent[bot] Jul 7, 2026
50374ab
feat(app): change traffic light position, fix sequoia bug (#35081)
arvsrn Jul 7, 2026
ae259d8
fix(app): apply settings themes on select (#35011)
opencode-agent[bot] Jul 7, 2026
64fd7a2
fix(app): persist session tab info (#34934)
Brendonovich Jul 7, 2026
c48b77d
chore: generate
opencode-agent[bot] Jul 7, 2026
c5fe32f
fix(app): show unread for pending questions (#34684)
opencode-agent[bot] Jul 7, 2026
65fd2e5
fix(app): prioritize shortcuts in terminal (#35668)
Brendonovich Jul 7, 2026
39397de
chore: generate
opencode-agent[bot] Jul 7, 2026
516f026
fix(app): hide markdown task markers (#35670)
Brendonovich Jul 7, 2026
ea9fffc
feat(data): redesign model efficiency
adamdotdevin Jul 7, 2026
1c25b2f
chore: generate
opencode-agent[bot] Jul 7, 2026
fd9ee43
fix(core): expand home-relative permission paths (#35737)
StarpTech Jul 7, 2026
888dc67
chore: generate
opencode-agent[bot] Jul 7, 2026
78f85b1
fix(core): ensure relevant files survive compaction (#35636)
opencode-agent[bot] Jul 7, 2026
adf178a
fix(llm): classify zai token limit overflow (#35671)
fengjikui Jul 7, 2026
5fb0d1c
release: v1.17.15
Jul 7, 2026
c274745
chore(termux): seed release automation
github-actions[bot] Jul 7, 2026
85f6fc2
Termux v1.17.14 (#10)
unemployabot[bot] Jul 7, 2026
f5439d6
Merge commit '85f6fc2154bf9719d1a39738998ff3aea64d152b' into checkpoi…
github-actions[bot] Jul 7, 2026
ffca5f8
Merge pull request #11 from wallentx/checkpoint-85f6fc2154bf
unemployabot[bot] Jul 7, 2026
e7a1dc6
chore(termux): seed release automation
github-actions[bot] Jul 7, 2026
4704a45
chore(termux): prepare v1.17.15
github-actions[bot] Jul 7, 2026
1545068
Merge branch 'release-1.17.15' into termux-1.17.15
wallentx Jul 7, 2026
7c27868
Merge pull request #12 from wallentx/termux-1.17.15
wallentx Jul 7, 2026
f0b69bf
Merge commit '7c27868828fada7db0edef21b0f7f3a174da5ee9' into checkpoi…
github-actions[bot] Jul 7, 2026
4c6a4b7
Merge pull request #13 from wallentx/checkpoint-7c27868828fa
unemployabot[bot] Jul 7, 2026
d37ed61
fix(ci): disable upstream housekeeping on forks
wallentx Jul 7, 2026
f4d01f4
chore(codegraph): Ignore generated data files
wallentx Jul 7, 2026
7b75f81
fix(termux): pin OpenTUI for Android build
wallentx Jul 8, 2026
56cbbbb
Termux v1.17.14 (#14)
unemployabot[bot] Jul 8, 2026
a305196
Merge commit '56cbbbb1b59bb6395fa70c56f7fa3f8fb75523f5' into checkpoi…
github-actions[bot] Jul 8, 2026
89d8950
Merge pull request #15 from wallentx/checkpoint-56cbbbb1b59b
unemployabot[bot] Jul 8, 2026
3103c02
chore(termux): prepare v1.17.14
github-actions[bot] Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .codegraph/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# CodeGraph data files — local to each machine, not for committing.
# Ignore everything in .codegraph/ except this file itself, so transient
# files (the database, daemon.pid, sockets, logs) never show up in git.
*
!.gitignore
12 changes: 12 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
self-hosted-runner:
labels:
- blacksmith-4vcpu-ubuntu-2404
- blacksmith-4vcpu-ubuntu-2404-arm
- blacksmith-4vcpu-windows-2025

config-variables: null

paths:
.github/workflows/docs-locale-sync.yml:
ignore:
- 'constant expression "false" in condition'
136 changes: 136 additions & 0 deletions .github/actions/build-android-cli/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
name: "Build Android CLI"
description: "Build and smoke-check the Android arm64 opencode artifact"
inputs:
version:
description: "Version to embed in the Android CLI"
required: true
release:
description: "Release flag passed to the opencode build"
required: false
default: ""
repo:
description: "Repository name passed to the opencode build"
required: true
runs:
using: "composite"
steps:
- uses: ./.github/actions/setup-bun

- name: Setup Zig
shell: bash
run: |
set -euo pipefail
zig_version=0.15.2
case "${RUNNER_OS}-${RUNNER_ARCH}" in
Linux-X64) zig_target="x86_64-linux" ;;
Linux-ARM64) zig_target="aarch64-linux" ;;
*) echo "Unsupported Zig host: ${RUNNER_OS}-${RUNNER_ARCH}" >&2; exit 1 ;;
esac

zig_dir="${RUNNER_TOOL_CACHE:-${RUNNER_TEMP}}/zig/${zig_version}/${zig_target}"
if [[ ! -x "${zig_dir}/zig" ]]; then
archive="${RUNNER_TEMP}/zig-${zig_target}-${zig_version}.tar.xz"
mkdir -p "${zig_dir}"
curl -fsSL "https://ziglang.org/download/${zig_version}/zig-${zig_target}-${zig_version}.tar.xz" -o "${archive}"
tar -xJf "${archive}" -C "${zig_dir}" --strip-components=1
fi

echo "${zig_dir}" >> "${GITHUB_PATH}"
"${zig_dir}/zig" version

- name: Install Bun build toolchain
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends wget gnupg software-properties-common ninja-build cmake file binutils
wget -qO "$RUNNER_TEMP/llvm.sh" https://apt.llvm.org/llvm.sh
chmod +x "$RUNNER_TEMP/llvm.sh"
sudo "$RUNNER_TEMP/llvm.sh" 21
sudo apt-get install -y --no-install-recommends clang-21 lld-21
LLVM_RESOURCE_DIR="$(clang-21 -print-resource-dir)"
NDK_PREBUILT="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64"
NDK_CLANG_VERSION="$(ls "$NDK_PREBUILT/lib/clang" | sort -V | tail -n 1)"
NDK_RUNTIME_DIR="$NDK_PREBUILT/lib/clang/$NDK_CLANG_VERSION/lib/linux"
sudo mkdir -p "$LLVM_RESOURCE_DIR/lib/aarch64-unknown-linux-android28" "$LLVM_RESOURCE_DIR/lib/linux/aarch64"
sudo ln -sf "$NDK_RUNTIME_DIR/libclang_rt.builtins-aarch64-android.a" "$LLVM_RESOURCE_DIR/lib/aarch64-unknown-linux-android28/libclang_rt.builtins.a"
sudo ln -sf "$NDK_RUNTIME_DIR/aarch64/libunwind.a" "$LLVM_RESOURCE_DIR/lib/aarch64-unknown-linux-android28/libunwind.a"
sudo ln -sf "$NDK_RUNTIME_DIR/libclang_rt.builtins-aarch64-android.a" "$LLVM_RESOURCE_DIR/lib/linux/libclang_rt.builtins-aarch64-android.a"
sudo ln -sf "$NDK_RUNTIME_DIR/aarch64/libunwind.a" "$LLVM_RESOURCE_DIR/lib/linux/aarch64/libunwind.a"

- name: Build Android Bun runtime with FFI
shell: bash
run: |
export CC=clang-21
export CXX=clang++-21
export LD=ld.lld-21
NDK_PREBUILT="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64"
mkdir -p "$RUNNER_TEMP/android-toolchain-bin"
ln -sf "$NDK_PREBUILT/bin/llvm-strip" "$RUNNER_TEMP/android-toolchain-bin/strip"
export PATH="$RUNNER_TEMP/android-toolchain-bin:$PATH"
BUN_VERSION="$(node -p "require('./package.json').packageManager.split('@')[1]")"
BUN_SOURCE="$RUNNER_TEMP/bun-src"
git clone --depth=1 --branch "bun-v${BUN_VERSION}" https://github.com/oven-sh/bun.git "$BUN_SOURCE"
BUN_BUILD="$BUN_SOURCE/build/android-ffi"
cd "$BUN_SOURCE"
bun install --frozen-lockfile
bun scripts/build.ts --profile=android-release --tinycc=on --build-dir="$BUN_BUILD" --target=bun -j"$(nproc)"
test -x "$BUN_BUILD/bun"
file "$BUN_BUILD/bun"
echo "OPENCODE_ANDROID_BUN=$BUN_BUILD/bun" >> "$GITHUB_ENV"

- name: Build Android CLI
shell: bash
run: ./packages/opencode/script/build.ts --target=android-arm64
env:
OPENCODE_VERSION: ${{ inputs.version }}
OPENCODE_RELEASE: ${{ inputs.release }}
GH_REPO: ${{ inputs.repo }}

- name: Smoke Android CLI artifact
shell: bash
run: |
set -euo pipefail
artifact_dir="packages/opencode/dist/opencode-android-arm64"
binary="${artifact_dir}/bin/opencode"
opentui_lib="packages/opencode/node_modules/@opentui/core/android-arm64/libopentui.so"
smoke_dir="packages/opencode/dist/android-smoke"
mkdir -p "$smoke_dir"

test -x "$binary"
file "$binary" | tee "$smoke_dir/file.txt"
readelf -h "$binary" | tee "$smoke_dir/readelf-header.txt"
readelf -l "$binary" | tee "$smoke_dir/readelf-program-headers.txt"
readelf -S "$binary" > "$smoke_dir/readelf-sections.txt"
readelf -d "$binary" | tee "$smoke_dir/readelf-dynamic.txt"

grep -q "Machine:.*AArch64" "$smoke_dir/readelf-header.txt"
grep -q "Type:.*DYN" "$smoke_dir/readelf-header.txt"
if grep -E "Requesting program interpreter: .*(ld-linux|ld-musl)" "$smoke_dir/readelf-program-headers.txt"; then
echo "Android artifact unexpectedly references a Linux ELF interpreter." >&2
exit 1
fi
if grep -E "Shared library: \\[(libc\\.so\\.6|ld-linux|ld-musl)" "$smoke_dir/readelf-dynamic.txt"; then
echo "Android artifact unexpectedly links Linux libc/runtime libraries." >&2
exit 1
fi

test -f "$opentui_lib"
file "$opentui_lib" | tee "$smoke_dir/opentui-file.txt"
readelf -d "$opentui_lib" | tee "$smoke_dir/opentui-readelf-dynamic.txt"
readelf -Ws "$opentui_lib" > "$smoke_dir/opentui-readelf-symbols.txt"
readelf -r "$opentui_lib" > "$smoke_dir/opentui-readelf-relocs.txt"

if grep -E "Shared library: \\[(libc\\.so\\.6|ld-linux|ld-musl|libstdc\\+\\+|libgcc_s)" "$smoke_dir/opentui-readelf-dynamic.txt"; then
echo "OpenTUI Android library unexpectedly links non-Android runtime libraries." >&2
exit 1
fi
if grep -E "Shared library: \\[(libc\\+\\+|libc\\+\\+_shared|libunwind)\\.so" "$smoke_dir/opentui-readelf-dynamic.txt"; then
echo "OpenTUI Android library requires an unbundled C++/unwind runtime." >&2
exit 1
fi
grep -E " (YGNode|facebook4yoga|yogaNode)" "$smoke_dir/opentui-readelf-symbols.txt" | head -80 || true

- name: Pack Android artifact
shell: bash
working-directory: packages/opencode/dist/opencode-android-arm64/bin
run: tar -czf ../../opencode-android-arm64.tar.gz *
175 changes: 175 additions & 0 deletions .github/scripts/termux-cleanup-release-branch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#!/usr/bin/env bash

set -euo pipefail

: "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is required}"
: "${GH_TOKEN:?GH_TOKEN is required}"

cleanup_limit="${CLEANUP_LIMIT:-100}"
cleanup_matched_checkpoint=false

append_cleanup_summary() {
local outcome="$1"
local release_branch="${2:-}"
local detail="${3:-}"

[[ -n "${GITHUB_STEP_SUMMARY:-}" ]] || return 0

{
echo "## Termux release branch cleanup"
echo
echo "- Outcome: ${outcome}"
if [[ -n "${release_branch}" ]]; then
echo "- Release branch: \`${release_branch}\`"
fi
if [[ -n "${detail}" ]]; then
echo "- Detail: ${detail}"
fi
} >> "${GITHUB_STEP_SUMMARY}"
}

checkpoint_source_branch() {
jq -r '
[
(.body // "")
| split("\n")[]
| try capture("^- Source branch: `(?<branch>[^`]+)`").branch catch empty
][0] // ""
' <<< "$1"
}

checkpoint_has_label() {
local checkpoint_json="$1"
local label="$2"

jq -e --arg label "${label}" '[.labels[]?.name] | index($label) != null' <<< "${checkpoint_json}" >/dev/null
}

release_branch_is_valid() {
[[ "$1" =~ ^release-[A-Za-z0-9._-]+$ ]]
}

open_prs_using_branch() {
local release_branch="$1"

gh pr list \
--repo "${GITHUB_REPOSITORY}" \
--state open \
--limit 200 \
--json number,title,url,headRefName,baseRefName,headRepository \
| jq \
--arg branch "${release_branch}" \
--arg repo "${GITHUB_REPOSITORY}" \
'
[
.[]
| select(
.baseRefName == $branch
or (
.headRefName == $branch
and ((.headRepository.nameWithOwner // "") == $repo)
)
)
]
'
}

delete_release_branch_if_unused() {
local release_branch="$1"
local checkpoint_url="$2"
local open_prs
local branch_sha

if ! release_branch_is_valid "${release_branch}"; then
echo "::warning::Refusing to delete unexpected release branch name: ${release_branch}"
append_cleanup_summary "skipped" "${release_branch}" "branch name did not match release-* cleanup policy"
return 0
fi

if ! branch_sha="$(gh api --method GET "repos/${GITHUB_REPOSITORY}/git/ref/heads/${release_branch}" --jq '.object.sha' 2>/dev/null)"; then
echo "${release_branch} no longer exists on ${GITHUB_REPOSITORY}."
append_cleanup_summary "already deleted" "${release_branch}" "remote branch was not found"
return 0
fi

open_prs="$(open_prs_using_branch "${release_branch}")"
if [[ "$(jq 'length' <<< "${open_prs}")" != "0" ]]; then
echo "Leaving ${release_branch} in place because open PRs still use it as a source or target:"
jq -r '.[] | "- #\(.number) \(.title) (\(.url))"' <<< "${open_prs}"
append_cleanup_summary "skipped" "${release_branch}" "open PRs still use this branch"
return 0
fi

gh api --silent --method DELETE "repos/${GITHUB_REPOSITORY}/git/refs/heads/${release_branch}"
echo "Deleted ${release_branch} at ${branch_sha} after merged checkpoint ${checkpoint_url}."
append_cleanup_summary "deleted" "${release_branch}" "checkpoint ${checkpoint_url} merged and no open PRs use the branch"
}

cleanup_checkpoint_pr() {
local checkpoint_json="$1"
local checkpoint_url
local release_branch

checkpoint_url="$(jq -r '.url // empty' <<< "${checkpoint_json}")"

if [[ "$(jq -r '.mergedAt // empty' <<< "${checkpoint_json}")" == "" ]]; then
echo "Checkpoint PR ${checkpoint_url:-unknown} is not merged yet; release branch cleanup is deferred."
append_cleanup_summary "deferred" "" "checkpoint PR is not merged yet"
return 0
fi

if ! checkpoint_has_label "${checkpoint_json}" "checkpoint" || ! checkpoint_has_label "${checkpoint_json}" "termux-release"; then
echo "Skipping ${checkpoint_url:-checkpoint PR}; it is not labeled as a Termux checkpoint."
return 0
fi

release_branch="$(checkpoint_source_branch "${checkpoint_json}")"
if [[ -z "${release_branch}" ]]; then
echo "::warning::Could not find release source branch in checkpoint PR ${checkpoint_url}."
append_cleanup_summary "skipped" "" "checkpoint PR did not include a source branch"
return 0
fi

if [[ -n "${SOURCE_BRANCH:-}" && "${release_branch}" != "${SOURCE_BRANCH}" ]]; then
echo "Skipping ${checkpoint_url}; source branch ${release_branch} does not match requested ${SOURCE_BRANCH}."
return 0
fi

cleanup_matched_checkpoint=true
delete_release_branch_if_unused "${release_branch}" "${checkpoint_url}"
}

if [[ -n "${CHECKPOINT_PR:-}" ]]; then
cleanup_checkpoint_pr "$(
gh pr view "${CHECKPOINT_PR}" \
--repo "${GITHUB_REPOSITORY}" \
--json number,title,body,baseRefName,headRefName,labels,mergedAt,state,url
)"
exit 0
fi

while IFS= read -r checkpoint_json; do
cleanup_checkpoint_pr "${checkpoint_json}"
done < <(
gh pr list \
--repo "${GITHUB_REPOSITORY}" \
--state merged \
--limit "${cleanup_limit}" \
--json number,title,body,baseRefName,headRefName,labels,mergedAt,state,url \
| jq -c '
.[]
| select(([.labels[]?.name] | index("checkpoint") != null))
| select(([.labels[]?.name] | index("termux-release") != null))
'
)

if [[ "${cleanup_matched_checkpoint}" == "false" ]]; then
if [[ -n "${SOURCE_BRANCH:-}" ]]; then
echo "No merged Termux checkpoint PR found for ${SOURCE_BRANCH} in the most recent ${cleanup_limit} merged PRs."
append_cleanup_summary "skipped" "${SOURCE_BRANCH}" "no merged checkpoint PR found"
exit 0
fi

echo "No merged Termux checkpoint PRs found in the most recent ${cleanup_limit} merged PRs."
append_cleanup_summary "skipped" "" "no merged checkpoint PRs found"
fi
37 changes: 37 additions & 0 deletions .github/scripts/termux-configure-git.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash

set -euo pipefail

git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

while (($#)); do
case "$1" in
--origin)
shift
origin_refs=()
while (($#)) && [[ "$1" != --* ]]; do
origin_refs+=("$1")
shift
done
if ((${#origin_refs[@]})); then
git fetch --prune origin "${origin_refs[@]}"
fi
;;
--upstream-tag)
if (($# < 3)); then
echo "--upstream-tag requires <repo> <tag>." >&2
exit 1
fi
upstream_repo="$2"
upstream_tag="$3"
git remote add upstream "https://github.com/${upstream_repo}.git" 2>/dev/null || true
git fetch --prune --no-tags upstream "+refs/tags/${upstream_tag}:refs/tags/${upstream_tag}"
shift 3
;;
*)
echo "Unknown argument: $1" >&2
exit 1
;;
esac
done
Loading
Loading