Add T3 Code nightly package (#793)

* Add T3 Code nightly package

* Hold a T3 Code nightly until its AppImages have uploaded

Upstream's release workflow publishes the GitHub release before softprops/action-gh-release uploads its assets: across the last 70 nightlies the AppImages finished 13 to 133 seconds after publication. A scheduled sync that lands in that window selects the release, finds no ARM AppImage to hash, and fails the shared sync run. A 30-minute minimum age, the hold omarchy-dev already uses, makes the watcher keep the previous nightly until the new one is complete.

Co-Authored-By: Codex XHigh <noreply@openai.com>

---------

Co-authored-by: Codex XHigh <noreply@openai.com>
This commit is contained in:
Spencer BullandCodex XHigh authored and GitHub committed 2026-10-04 01:35:33 -05:00
1 parent 3dcab43846
commit a79eec1006
6 files changed
+221

No files matched your search

@@ -0,0 +1,13 @@
{
"source": "local",
"release_ring": "fast",
"min_release_age": "30m",
"upstream": {
"watch": {
"github": "pingdotgg/t3code",
"pattern": "v(?P<version>[0-9]+\\.[0-9]+\\.[0-9]+)-nightly\\.(?P<date>[0-9]{8})\\.(?P<run>[0-9]+)",
"version": "{version}_nightly.{date}.{run}",
"allow_prerelease": true
}
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 T3 Tools Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+131
View File
@@ -0,0 +1,131 @@
# Maintainer: David Heinemeier Hansson <david@hey.com>
# T3 Code ships its Linux desktop as an AppImage, so Omarchy unpacks it and
# keeps only the Electron tree. AppRun, the compatibility libraries bundled for
# distributions that do not ship their own, and the AppImage's icon shims are all
# dead weight here. The upstream watch tracks only nightly release tags and
# updates the version and architecture-specific checksums together.
pkgname=t3code-nightly-bin
pkgver=0.0.46_nightly.20261004.2644
_upstream_version=${pkgver/_/-}
pkgrel=1
pkgdesc="Open-source control plane for coding agents (nightly)"
arch=('x86_64' 'aarch64')
url="https://t3.codes"
license=('MIT')
makedepends=('7zip')
depends=(
'alsa-lib'
'at-spi2-core'
'cairo'
'dbus'
'expat'
'gcc-libs'
'glib2'
'glibc'
'gtk3'
'hicolor-icon-theme'
'libcups'
'libnotify'
'libx11'
'libxcb'
'libxcomposite'
'libxdamage'
'libxext'
'libxfixes'
'libxkbcommon'
'libxrandr'
'mesa'
'nspr'
'nss'
'pango'
'systemd-libs'
'xdg-utils'
)
optdepends=(
'claude-code: drive Claude Code from the app'
'cursor-cli: drive Cursor from the app'
'github-copilot-cli: drive Copilot from the app'
'openai-codex: drive Codex from the app'
)
provides=("t3code-nightly=${pkgver}")
conflicts=('t3code-nightly')
options=('!debug' '!strip')
_appimage_x86_64="T3-Code-${_upstream_version}-x86_64.AppImage"
_appimage_aarch64="T3-Code-${_upstream_version}-arm64.AppImage"
source=('t3code-launcher.sh' 't3-launcher.sh' 'LICENSE')
source_x86_64=("https://github.com/pingdotgg/t3code/releases/download/v${_upstream_version}/${_appimage_x86_64}")
source_aarch64=("https://github.com/pingdotgg/t3code/releases/download/v${_upstream_version}/${_appimage_aarch64}")
noextract=("${_appimage_x86_64}" "${_appimage_aarch64}")
sha256sums=('55e9aca82941ba21daff12e67f5b6c8a2ecbd30eb0ff9fc6c6a625dfc5aacd51'
'85572a955d917fc92da30f6d0ea515370c97950aefc8e12eb25c3673aa4cca6e'
'935d8f2af0c703f9c39517ee57cc4930b19d02d533be930b63f0e82f93614b43')
sha256sums_x86_64=('7521793d4dc87f2b985f88b48b070bedf33a1f590cca34a96c9e7ca0b1fe298b')
sha256sums_aarch64=('784939b3fc0aec185df9148893c22b0ae10abb6e32d03905474c5a43ba511508')
prepare() {
local _appimage
case "$CARCH" in
x86_64) _appimage="${_appimage_x86_64}" ;;
aarch64) _appimage="${_appimage_aarch64}" ;;
esac
rm -rf "${srcdir}/squashfs-root"
# Extract without executing the runtime: AppImage's ELF magic does not match
# QEMU's binfmt registration when building ARM packages on an x86_64 host.
7z x "${srcdir}/${_appimage}" -o"${srcdir}/squashfs-root" >/dev/null
}
package() {
cd "${srcdir}/squashfs-root"
# The AppImage's usr/ tree is compatibility libraries for distributions that
# lack them, and Arch is not one; its icons are the only part worth keeping.
# A release that starts shipping something else there stops the build rather
# than having it deleted quietly on the way past.
local unexpected
unexpected=$(find usr \( -type f -o -type l \) | grep -vE \
'^usr/share/icons/hicolor/[0-9]+x[0-9]+/apps/t3code\.png$|^usr/lib/lib(Xss\.so\.1|Xtst\.so\.6|appindicator\.so\.1|gconf-2\.so\.4|indicator\.so\.7|notify\.so\.4)$' || true)
if [[ -n "${unexpected}" ]]; then
echo "Unexpected files in the AppImage's usr/ tree:" >&2
echo "${unexpected}" >&2
return 1
fi
local icon size
for icon in usr/share/icons/hicolor/*/apps/t3code.png; do
size="${icon#usr/share/icons/hicolor/}"
install -Dm644 "${icon}" "${pkgdir}/usr/share/icons/hicolor/${size%%/*}/apps/t3code-nightly.png"
done
# Upstream's own entry rather than a hand-written one: it carries the
# t3code:// scheme handlers that make the app's deep links resolve.
# Separate desktop and icon names allow installation alongside stable.
# Application state and URL schemes retain upstream's shared-channel behavior.
sed -e 's|^Exec=.*|Exec=t3code-nightly %U|' -e 's|^Name=.*|Name=T3 Code (Nightly)|' \
-e 's|^Icon=.*|Icon=t3code-nightly|' -e '/^X-AppImage-Version=/d' t3code.desktop \
> "${srcdir}/t3code.desktop.arch"
install -Dm644 "${srcdir}/t3code.desktop.arch" \
"${pkgdir}/usr/share/applications/t3code-nightly.desktop"
rm -rf AppRun .DirIcon usr t3code.desktop t3code.png
install -d "${pkgdir}/usr/lib/t3code-nightly"
cp -a . "${pkgdir}/usr/lib/t3code-nightly/"
chmod -R a+rX "${pkgdir}/usr/lib/t3code-nightly"
# Arch ships Chromium's and Electron's own sandbox helper setuid, which is
# what keeps the sandbox up on a kernel that denies unprivileged user
# namespaces -- linux-hardened, mainly -- instead of aborting the app.
chmod 4755 "${pkgdir}/usr/lib/t3code-nightly/chrome-sandbox"
install -Dm755 "${srcdir}/t3code-launcher.sh" "${pkgdir}/usr/bin/t3code-nightly"
# The server CLI, run through the bundled Electron as Node. Same entrypoint
# npm's `t3` package runs, so `t3 serve`, `t3 pair`, and the rest work
# without a separate install.
install -Dm755 "${srcdir}/t3-launcher.sh" "${pkgdir}/usr/bin/t3-nightly"
install -Dm644 "${srcdir}/LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
+15
View File
@@ -0,0 +1,15 @@
# T3 Code Nightly
`t3code-nightly-bin` packages upstream nightly releases for x86_64 and aarch64.
Run `t3code-nightly` for the desktop or `t3-nightly` for the server CLI.
The app launcher entry is **T3 Code (Nightly)**. Optional Electron flags go in
`~/.config/t3code-nightly-flags.conf` (or under `$XDG_CONFIG_HOME`).
The package can be installed alongside `t3code-bin`, with separate binaries,
icons, and desktop entries. Upstream still shares its application data and URL
schemes between channels: installing both does not create isolated profiles.
The upstream watch accepts only `vX.Y.Z-nightly.YYYYMMDD.N` releases. Arch versions
replace the hyphen with an underscore; downloads retain upstream's original tag
and filenames. Both architecture checksums must be available before an update.
A nightly is picked up once it is 30 minutes old, because upstream publishes the release before its AppImages finish uploading.
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
# The T3 Code server CLI (`t3`) ships inside the app bundle.
# The bundled Electron doubles as the
# Node runtime for it, so the desktop package can put the CLI on PATH without
# shipping a second runtime. Electron's fs layer reads app.asar transparently
# in this mode.
set -euo pipefail
export ELECTRON_RUN_AS_NODE=1
exec /usr/lib/t3code-nightly/t3code /usr/lib/t3code-nightly/resources/app.asar/apps/server/dist/bin.mjs "$@"
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
set -euo pipefail
user_flags=()
config_home="${XDG_CONFIG_HOME:-}"
[[ -n "$config_home" || -z "${HOME:-}" ]] || config_home="$HOME/.config"
flags_file="${config_home:+$config_home/t3code-nightly-flags.conf}"
if [[ -n "$flags_file" && -f "$flags_file" && -r "$flags_file" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
line="${line%%#*}"
[[ -n "${line//[[:space:]]/}" ]] || continue
read -r -a flags <<<"$line"
user_flags+=("${flags[@]}")
done <"$flags_file"
fi
# Chromium's own Ozone detection falls back to XWayland often enough to matter,
# and the result is a blurry window on every scaled display.
platform_flags=()
if [[ -n "${WAYLAND_DISPLAY:-}" || "${XDG_SESSION_TYPE:-}" == wayland ]]; then
platform_flags=(--ozone-platform=wayland)
for flag in "${user_flags[@]}" "$@"; do
case "$flag" in
--ozone-platform=* | --ozone-platform-hint=*) platform_flags=() ;;
esac
done
fi
exec /usr/lib/t3code-nightly/t3code "${platform_flags[@]}" "${user_flags[@]}" "$@"