sha256:82865e6bca2963bf6f2ff532f312c76a38faeef0e1703fd7d5dac227e4c85e9a
Last pushed
1 day by maidok
Type
Sandbox Kit
Manifest digest
sha256:82865e6bca2963bf6f2ff532f312c76a38faeef0e1703fd7d5dac227e4c85e9a
schemaVersion: "3"
displayName: T3 Code workspace project
description: Registers the sandbox workspace as a T3 Code project, defaults new threads to a worktree, routes GitHub SSH remotes over HTTPS, and installs mise with the workspace's tools, so T3 Code can start work right away. Use with the t3code kit.
kind: mixin
capabilities:
- type: com.docker.sandbox/network-policy@1
config:
runtime:
allow:
- mise.jdx.dev:443
- mise-versions.jdx.dev:443
- mise-java.jdx.dev:443
- nodejs.org:443
- github.com:443
- '*.githubusercontent.com:443'
- type: com.docker.sandbox/lifecycle@1
config:
startup:
- command:
- sh
- -c
- |
# Every bash in the sandbox sources /etc/sandbox-persistent.sh
# (BASH_ENV, /etc/profile.d and ~/.bashrc), so agents' shell
# commands pick this up. Shims go first on PATH, ahead of the
# base image's java; `mise env` also sets JAVA_HOME and friends
# for the current directory, overriding the base image's value.
set -e
f=/etc/sandbox-persistent.sh
[ -w "$f" ] || { echo "$f not writable; skipping"; exit 0; }
trusted="${WORKSPACE_DIR:+$WORKSPACE_DIR:}$HOME/.t3/worktrees"
# /etc itself isn't writable by the agent, only the file is: stage
# the new content in /tmp, then rewrite the file in place.
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
sed '/^# >>> mise (t3-workspace-project) >>>$/,/^# <<< mise (t3-workspace-project) <<<$/d' "$f" > "$tmp"
cat >> "$tmp" <<EOF
# >>> mise (t3-workspace-project) >>>
export MISE_TRUSTED_CONFIG_PATHS="$trusted"
case ":\$PATH:" in *":$HOME/.local/share/mise/shims:"*) ;; *) export PATH="$HOME/.local/share/mise/shims:\$PATH" ;; esac
if command -v mise >/dev/null 2>&1; then eval "\$(mise env -s bash 2>/dev/null)"; fi
# <<< mise (t3-workspace-project) <<<
EOF
cat "$tmp" > "$f"
echo "mise activated in $f (trusted: $trusted)"
description: Activate mise in every shell
env:
- WORKSPACE_DIR
- background: true
command:
- sh
- -c
- |
dir="${WORKSPACE_DIR:-}"
[ -n "$dir" ] || { echo "WORKSPACE_DIR is not set; skipping"; exit 0; }
command -v mise >/dev/null 2>&1 || { echo "mise not found; skipping"; exit 0; }
i=0; while [ ! -d "$dir" ] && [ "$i" -lt 60 ]; do sleep 1; i=$((i+1)); done
cd "$dir" || exit 0
export MISE_TRUSTED_CONFIG_PATHS="$dir:$HOME/.t3/worktrees" MISE_YES=1
mise install && echo "mise tools installed for $dir"
description: Install the workspace's mise tools
env:
- WORKSPACE_DIR
- HTTP_PROXY
- HTTPS_PROXY
- NO_PROXY
- http_proxy
- https_proxy
- no_proxy
- SSL_CERT_FILE
- SSL_CERT_DIR
- command:
- sh
- -c
- |
# The sandbox proxy blocks SSH (port 22), so T3's `git fetch` on a
# [email protected]: origin fails. Rewrite to HTTPS and let gh supply
# the token. Idempotent: values are reset before being added.
command -v gh >/dev/null 2>&1 || { echo "gh not found; skipping"; exit 0; }
git config --global --unset-all url.https://github.com/.insteadOf 2>/dev/null || true
git config --global --add url.https://github.com/.insteadOf [email protected]:
git config --global --add url.https://github.com/.insteadOf ssh://[email protected]/
git config --global --unset-all credential.https://github.com.helper 2>/dev/null || true
git config --global --add credential.https://github.com.helper ''
git config --global --add credential.https://github.com.helper '!gh auth git-credential'
echo "GitHub remotes now use HTTPS with gh credentials"
description: Route GitHub SSH remotes over HTTPS via gh
- command:
- sh
- -c
- |
# Server settings live in the t3 base dir (~/.t3, as passed by
# T3 Code's SSH launch). Merge rather than overwrite so settings
# changed in the UI survive. Re-applied every boot.
f="$HOME/.t3/userdata/settings.json"
mkdir -p "$(dirname "$f")"
if [ ! -s "$f" ]; then
printf '{\n "defaultThreadEnvMode": "worktree"\n}\n' > "$f"
elif command -v jq >/dev/null 2>&1; then
tmp="$f.tmp.$$"
jq '.defaultThreadEnvMode = "worktree"' "$f" > "$tmp" && mv "$tmp" "$f" || { rm -f "$tmp"; exit 1; }
else
echo "jq not found; leaving existing $f unchanged"; exit 0
fi
echo "T3 Code new threads default to a worktree"
description: Default new T3 Code threads to a worktree
- command:
- sh
- -c
- |
dir="${WORKSPACE_DIR:-}"
[ -n "$dir" ] || { echo "WORKSPACE_DIR is not set; skipping"; exit 0; }
# Clone-mode sandboxes may still be populating the workspace.
i=0; while [ ! -d "$dir" ] && [ "$i" -lt 60 ]; do sleep 1; i=$((i+1)); done
# The t3code kit's `t3` launcher is a node script, and agent images
# may not ship node, so call the bundled native binary directly.
t3=$(ls /opt/t3/lib/node_modules/t3/node_modules/@t3code/t3-linux-*/t3 2>/dev/null | head -n1)
[ -x "$t3" ] || t3=$(command -v t3 || true)
[ -n "$t3" ] || { echo "t3 not found; add the t3code kit"; exit 0; }
out=$("$t3" project add --title "$(basename "$dir")" "$dir" 2>&1) && { echo "Added T3 project for $dir"; exit 0; }
case "$out" in
*ProjectAlreadyExistsError*) echo "T3 project for $dir already exists" ;;
*) printf '%s\n' "$out" >&2; exit 1 ;;
esac
description: Register the workspace as a T3 Code project
env:
- WORKSPACE_DIR
args:
miseVersion:
default: 2026.11.5
description: mise release to install
pattern: ^[0-9]+\.[0-9]+\.[0-9]+$
buildArg: MISE_VERSION
build: |
FROM alpine:3 AS build
ARG TARGETARCH
ARG MISE_VERSION
RUN apk add --no-cache curl
RUN set -eux; \
case "$TARGETARCH" in amd64) arch=x64 ;; arm64) arch=arm64 ;; *) echo "unsupported: $TARGETARCH"; exit 1 ;; esac; \
f="mise-v${MISE_VERSION}-linux-${arch}-musl"; \
base="https://github.com/jdx/mise/releases/download/v${MISE_VERSION}"; \
cd /tmp; \
curl -fsSLO "$base/$f"; \
curl -fsSL "$base/SHASUMS256.txt" | grep " ./$f\$" | sed 's# ./# #' | sha256sum -c -; \
install -D -m 0755 "$f" /out/usr/local/bin/mise; \
/out/usr/local/bin/mise --version | grep -q "$MISE_VERSION"
FROM scratch
COPY --from=build /out /