Merge pull request #159 from abu-matterize/fix/opencode-color-compat

Solid hardening — NO_COLOR support, hex validation, portable ANSI stripping. Nice work!
This commit is contained in:
Michael Sitarzewski 2026-03-12 07:48:52 -05:00 committed by GitHub
commit 22396b6d96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 28 deletions

View File

@ -25,7 +25,7 @@
set -euo pipefail
# --- Colour helpers ---
if [[ -t 1 ]]; then
if [[ -t 1 && -z "${NO_COLOR:-}" && "${TERM:-}" != "dumb" ]]; then
GREEN=$'\033[0;32m'; YELLOW=$'\033[1;33m'; RED=$'\033[0;31m'; BOLD=$'\033[1m'; RESET=$'\033[0m'
else
GREEN=''; YELLOW=''; RED=''; BOLD=''; RESET=''
@ -128,33 +128,48 @@ ${body}
HEREDOC
}
# Map named colors to hex codes for OpenCode (which only accepts hex values).
# Colors already starting with '#' pass through unchanged.
# Map known color names and normalize to OpenCode-safe #RRGGBB values.
resolve_opencode_color() {
local c="$1"
local mapped
c="$(printf '%s' "$c" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr '[:upper:]' '[:lower:]')"
case "$c" in
cyan) echo "#00FFFF" ;;
blue) echo "#3498DB" ;;
green) echo "#2ECC71" ;;
red) echo "#E74C3C" ;;
purple) echo "#9B59B6" ;;
orange) echo "#F39C12" ;;
teal) echo "#008080" ;;
indigo) echo "#6366F1" ;;
pink) echo "#E84393" ;;
gold) echo "#EAB308" ;;
amber) echo "#F59E0B" ;;
neon-green) echo "#10B981" ;;
neon-cyan) echo "#06B6D4" ;;
metallic-blue) echo "#3B82F6" ;;
yellow) echo "#EAB308" ;;
violet) echo "#8B5CF6" ;;
rose) echo "#F43F5E" ;;
lime) echo "#84CC16" ;;
gray) echo "#6B7280" ;;
fuchsia) echo "#D946EF" ;;
*) echo "$c" ;; # already hex or unknown — pass through
cyan) mapped="#00FFFF" ;;
blue) mapped="#3498DB" ;;
green) mapped="#2ECC71" ;;
red) mapped="#E74C3C" ;;
purple) mapped="#9B59B6" ;;
orange) mapped="#F39C12" ;;
teal) mapped="#008080" ;;
indigo) mapped="#6366F1" ;;
pink) mapped="#E84393" ;;
gold) mapped="#EAB308" ;;
amber) mapped="#F59E0B" ;;
neon-green) mapped="#10B981" ;;
neon-cyan) mapped="#06B6D4" ;;
metallic-blue) mapped="#3B82F6" ;;
yellow) mapped="#EAB308" ;;
violet) mapped="#8B5CF6" ;;
rose) mapped="#F43F5E" ;;
lime) mapped="#84CC16" ;;
gray) mapped="#6B7280" ;;
fuchsia) mapped="#D946EF" ;;
*) mapped="$c" ;;
esac
if [[ "$mapped" =~ ^#[0-9a-fA-F]{6}$ ]]; then
printf '#%s\n' "$(printf '%s' "${mapped#\#}" | tr '[:lower:]' '[:upper:]')"
return
fi
if [[ "$mapped" =~ ^[0-9a-fA-F]{6}$ ]]; then
printf '#%s\n' "$(printf '%s' "$mapped" | tr '[:lower:]' '[:upper:]')"
return
fi
printf '#6B7280\n'
}
convert_opencode() {
@ -177,7 +192,7 @@ convert_opencode() {
name: ${name}
description: ${description}
mode: subagent
color: ${color}
color: '${color}'
---
${body}
HEREDOC

View File

@ -33,9 +33,9 @@
set -euo pipefail
# ---------------------------------------------------------------------------
# Colours -- only when stdout is a real terminal
# Colours -- only when stdout supports color
# ---------------------------------------------------------------------------
if [[ -t 1 ]]; then
if [[ -t 1 && -z "${NO_COLOR:-}" && "${TERM:-}" != "dumb" ]]; then
C_GREEN=$'\033[0;32m'
C_YELLOW=$'\033[1;33m'
C_RED=$'\033[0;31m'
@ -63,11 +63,14 @@ BOX_INNER=48 # chars between the two | walls
box_top() { printf " +"; printf '%0.s-' $(seq 1 $BOX_INNER); printf "+\n"; }
box_bot() { box_top; }
box_sep() { printf " |"; printf '%0.s-' $(seq 1 $BOX_INNER); printf "|\n"; }
strip_ansi() {
awk '{ gsub(/\033\[[0-9;]*m/, ""); print }' <<< "$1"
}
box_row() {
# Strip ANSI escapes when measuring visible length
local raw="$1"
local visible
visible="$(printf '%s' "$raw" | sed 's/\x1b\[[0-9;]*m//g')"
visible="$(strip_ansi "$raw")"
local pad=$(( BOX_INNER - 2 - ${#visible} ))
if (( pad < 0 )); then pad=0; fi
printf " | %s%*s |\n" "$raw" "$pad" ''