Give the sandbox a UTF-8 locale
A sandbox image ships without a locale, leaving LC_CTYPE at POSIX. Every multibyte glyph then degrades to a placeholder, so Nerd Font icons in the editor render as underscores and bash printf emits \uXXXX escapes literally. The locale is probed for usability rather than matched by name, because locale -a spells C.UTF-8 as C.utf8 on glibc and a name match would silently find nothing. LANG alone is set, leaving individual categories overridable.
This commit is contained in:
@@ -1055,6 +1055,39 @@ EOF
|
||||
'
|
||||
}
|
||||
|
||||
# A sandbox image ships without a locale, which leaves LC_CTYPE at POSIX. Every
|
||||
# multibyte glyph then degrades to a placeholder: Nerd Font icons in the editor
|
||||
# render as underscores, and bash printf emits \uXXXX escapes literally. LANG
|
||||
# alone is enough, and leaves a user free to override individual categories.
|
||||
install_sandbox_locale() {
|
||||
# shellcheck disable=SC2016
|
||||
sbx exec "$SANDBOX_NAME" bash -c '
|
||||
persistent=/etc/sandbox-persistent.sh
|
||||
marker="# BEGIN ai-sbx locale"
|
||||
|
||||
if grep -Fq "$marker" "$persistent" 2>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# locale -a spells these inconsistently across distributions, so probe
|
||||
# each one for usability rather than matching its name.
|
||||
for candidate in C.UTF-8 en_US.UTF-8; do
|
||||
if LC_ALL="$candidate" locale >/dev/null 2>&1; then
|
||||
chosen="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
[[ -n "${chosen:-}" ]] || exit 0
|
||||
|
||||
cat >>"$persistent" <<EOF
|
||||
# BEGIN ai-sbx locale
|
||||
export LANG=$chosen
|
||||
# END ai-sbx locale
|
||||
EOF
|
||||
' </dev/null >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
validate_launch_mode() {
|
||||
case "$1" in
|
||||
agent | tmux) ;;
|
||||
@@ -1427,6 +1460,8 @@ run_command() {
|
||||
# runs every time rather than only at setup.
|
||||
install_sandbox_mise
|
||||
|
||||
install_sandbox_locale
|
||||
|
||||
if [[ "$launch" == tmux ]]; then
|
||||
install_sandbox_workspace
|
||||
|
||||
|
||||
@@ -47,8 +47,12 @@ dispatch() {
|
||||
cat "$SBX_LOG"
|
||||
}
|
||||
|
||||
[[ "$DEFAULT_LAUNCH" == agent ]] ||
|
||||
fail "AI_SBX_LAUNCH unset should default to agent, got: $DEFAULT_LAUNCH"
|
||||
(
|
||||
unset AI_SBX_LAUNCH
|
||||
# shellcheck source=tasks/ai/sbx
|
||||
source "$TASK"
|
||||
[[ "$DEFAULT_LAUNCH" == agent ]]
|
||||
) || fail "AI_SBX_LAUNCH unset should default to agent"
|
||||
|
||||
(
|
||||
AI_SBX_LAUNCH=tmux
|
||||
@@ -87,6 +91,13 @@ DEFAULT_LAUNCH=agent
|
||||
[[ "$(dispatch -- --launch tmux)" == *"run ai-test -- --launch tmux"* ]] ||
|
||||
fail "--launch after -- belongs to the agent, not to the task"
|
||||
|
||||
DEFAULT_LAUNCH=agent
|
||||
locale_dispatch="$(dispatch)"
|
||||
[[ "$locale_dispatch" == *"BEGIN ai-sbx locale"* ]] ||
|
||||
fail "run should install a UTF-8 locale, or Nerd Font glyphs render as placeholders: $locale_dispatch"
|
||||
[[ "$locale_dispatch" == *"LC_ALL=\"\$candidate\" locale"* ]] ||
|
||||
fail "the locale must be probed for usability, not matched by name against locale -a"
|
||||
|
||||
if (validate_launch_mode bogus) 2>/dev/null; then
|
||||
fail "an unknown launch mode was accepted"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user