Commit 8e487009 by jaysurplus@126.com

docs(iteration): 归档项目迭代 V0.2.1 - 修复 TUI 状态渲染

移除导致 whiptail 边框错位的双列彩色 emoji。

保留完全中文状态文字,并由 dialog 和普通终端提供彩色圆点显示。
parent bec7fccd
......@@ -14,7 +14,7 @@
- 识别路由的“已启用”“部分启用”和“已禁用”状态。
- 禁用时只移除本脚本管理的两个网段,保留设备上其他 advertised routes。
- 仅在 forwarding 由本脚本修改时恢复原始状态。
- 优先使用 `whiptail`,其次使用 `dialog`,否则使用普通终端菜单。
- 优先使用支持逐段着色的 `dialog`,其次使用 `whiptail`,否则使用普通终端菜单。
- 对安装、运行、连接和 Route 状态使用统一的状态颜色。
## TUI 导航规则
......@@ -35,7 +35,13 @@
| 黄色 | 未知或部分生效 | 服务状态未知、路由部分启用 |
| 红色 | 未就绪或已禁用 | 未安装、服务已停止、未连接、路由已禁用 |
普通终端使用 ANSI 颜色;`whiptail` 和 `dialog` 使用彩色圆点,避免依赖不同 TUI 后端的私有颜色语法。输出被重定向、`TERM=dumb` 或设置了 [`NO_COLOR`](https://no-color.org/) 时,普通终端状态自动退回纯文本。
状态文字完全使用中文,例如“已安装”“运行中”“已连接”“已启用”。普通终端使用 ANSI 彩色圆点,`dialog` 使用自身的颜色语法显示彩色圆点。`whiptail/newt` 不能可靠地在同一文本框中逐行着色,并且彩色 emoji 会造成边框错位,因此仅显示中文状态文字作为兼容后备。输出被重定向、`TERM=dumb` 或设置了 [`NO_COLOR`](https://no-color.org/) 时,普通终端状态自动退回纯文本。
要在完整 TUI 中获得逐状态颜色,请在 Ubuntu/Debian 目标设备安装 `dialog`:
```bash
sudo apt-get install -y dialog
```
## 支持环境
......
......@@ -4,5 +4,5 @@
| --- | --- | --- |
| Agent 治理骨架 | Done | AGENTS、workflow、rule、skill 与多 Agent 适配层已初始化 |
| 脚本安全约束 | Done | 已定义敏感信息、幂等、权限、危险操作与验证边界 |
| Tailscale Route Manager | Done (V0.2.0) | 安装 Tailscale,并管理两个 QArm 局域网的 subnet routes、forwarding 与中文彩色 TUI |
| Tailscale Route Manager | Done (V0.2.1) | 安装 Tailscale,并管理两个 QArm 局域网的 subnet routes、forwarding 与中文彩色 TUI;已修复 `whiptail` 边框错位 |
| 其他 QArm 业务配置脚本 | Pending | 等待后续按真实目标平台和配置需求添加 |
# 迭代记录
## [V0.2.1] 修复 TUI 状态渲染 (Fix TUI Status Rendering)
- **功能**: 修复 `whiptail/newt` 因彩色 emoji 双列宽度导致的右侧边框错位,同时保留完全中文的状态文字和可用环境中的红、黄、绿状态颜色。
- **改动文件**:
- `scripts/tailscale/tailscale-route-manager.sh`: 移除双列 emoji;优先使用支持逐段颜色的 `dialog`,普通终端使用 ANSI 彩色圆点,`whiptail` 使用纯中文兼容渲染。
- `docs/tailscale/README.md`: 说明不同 TUI 后端的颜色能力、中文状态和 `dialog` 安装方式。
- `meta/REGRESSION.md`: 增加 `whiptail` 边框宽度与中文彩色状态回归项。
- **影响**: 状态页不再因 emoji 宽度破坏右边框;未安装 `dialog` 时仍可使用无逐行颜色的中文 `whiptail` 后备。真实目标终端中的视觉效果仍需现场复验。
## [V0.2.0] Tailscale 子网路由管理器 (Tailscale Route Manager)
- **功能**: 新增面向 QArm Linux 目标设备的 Tailscale 安装与子网路由管理工具,管理 `192.168.11.0/24`、`192.168.22.0/24`,并提供中文彩色 TUI、转发状态恢复和单出口导航。
......
{
"project_name": "qarm_setup_scripts",
"version": "0.2.0",
"iteration_count": 2,
"version": "0.2.1",
"iteration_count": 3,
"last_update": "2026-09-21",
"stack_summary": [
"PowerShell",
......@@ -35,6 +35,8 @@
"tailscale_route_manager_ready": true,
"tailscale_status_color_ready": true,
"tailscale_tui_single_exit_ready": true,
"tailscale_cancel_flow_ready": true
"tailscale_cancel_flow_ready": true,
"tailscale_whiptail_width_safe": true,
"tailscale_dialog_color_ready": true
}
}
......@@ -17,6 +17,7 @@
| 路由集合保护 | 启用时合并、禁用时仅移除两个 managed routes | Ready |
| Forwarding 恢复 | IPv4/IPv6 原始状态均能独立记录和恢复 | Pending |
| 目标设备端到端路由 | 从 tailnet 客户端访问两个 QArm 局域网 | Pending |
| Tailscale 状态颜色 | TUI 显示彩色圆点;交互终端显示 ANSI;重定向或 `NO_COLOR` 时为纯文本 | Ready |
| Tailscale 状态颜色 | `dialog` 与交互终端显示彩色圆点和中文状态,`whiptail` 仅显示中文状态,重定向或 `NO_COLOR` 时为纯文本 | Ready |
| Whiptail 边框宽度 | 状态文本不得包含双列 emoji;右侧边框不因状态行发生错位 | Ready |
| Tailscale TUI 单出口 | 分支完成、取消、Esc 或失败后返回主页面;仅主页面“退出”结束 TUI | Ready |
| 未登录时取消启用 | `tailscale up` 确认框选择 No 后不退出脚本,直接返回主页面 | Ready |
......@@ -11,7 +11,7 @@ set -euo pipefail
# 首次启用 forwarding 前记录的内核状态。
readonly INSTALL_URL="https://tailscale.com/install.sh"
readonly SCRIPT_VERSION="0.2.0"
readonly SCRIPT_VERSION="0.2.1"
readonly RC_CANCELLED=10
readonly SYSCTL_FILE="/etc/sysctl.d/99-tailscale-routes.conf"
readonly STATE_FILE="/var/lib/tailscale-route-manager.state"
......@@ -53,11 +53,11 @@ message_box() {
local title="$1"
local message="$2"
if command_exists whiptail; then
whiptail --title "$title" --msgbox "$message" 22 76 || true
elif command_exists dialog; then
dialog --title "$title" --msgbox "$message" 22 76 || true
if command_exists dialog; then
dialog --colors --title "$title" --msgbox "$message" 22 76 || true
clear || true
elif command_exists whiptail; then
whiptail --title "$title" --msgbox "$message" 22 76 || true
else
clear || true
printf '============================================================\n'
......@@ -72,13 +72,13 @@ yes_no() {
local title="$1"
local message="$2"
if command_exists whiptail; then
whiptail --title "$title" --yesno "$message" 18 76
elif command_exists dialog; then
if command_exists dialog; then
dialog --title "$title" --yesno "$message" 18 76
local result=$?
clear || true
return "$result"
elif command_exists whiptail; then
whiptail --title "$title" --yesno "$message" 18 76
else
printf '\n%s\n\n' "$message"
read -r -p "[y/N]: " answer
......@@ -500,24 +500,24 @@ format_status_value() {
local label="$2"
local mode="$3"
local ansi_color
local tui_icon
local dialog_color
case "$severity" in
ok)
ansi_color="32"
tui_icon="🟢"
dialog_color="2"
;;
warn)
ansi_color="33"
tui_icon="🟡"
dialog_color="3"
;;
error)
ansi_color="31"
tui_icon="🔴"
dialog_color="1"
;;
*)
ansi_color="37"
tui_icon="⚪"
dialog_color="7"
;;
esac
......@@ -525,8 +525,12 @@ format_status_value() {
ansi)
printf '\033[%sm● %s\033[0m' "$ansi_color" "$label"
;;
tui)
printf '%s %s' "$tui_icon" "$label"
whiptail)
# newt/whiptail 不支持可靠的逐行颜色,且彩色 emoji 会破坏右侧边框。
printf '%s' "$label"
;;
dialog)
printf '\\Z%s● %s\\Zn' "$dialog_color" "$label"
;;
*)
printf '%s' "$label"
......@@ -622,8 +626,10 @@ run_main_action() {
show_status() {
local mode="text"
if command_exists whiptail || command_exists dialog; then
mode="tui"
if command_exists dialog; then
mode="dialog"
elif command_exists whiptail; then
mode="whiptail"
elif [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]] && [[ "${TERM:-}" != "dumb" ]]; then
mode="ansi"
fi
......@@ -645,22 +651,22 @@ run_menu() {
local choice
action="$(get_main_action)"
if command_exists whiptail; then
if ! choice="$(whiptail --nocancel --title "Tailscale 路由管理器" \
--menu "$(get_status_text tui)\n\n请选择操作:" 30 78 6 \
if command_exists dialog; then
if ! choice="$(dialog --colors --stdout --no-cancel --title "Tailscale 路由管理器" \
--menu "$(get_status_text dialog)\n\n请选择操作:" 30 78 6 \
"toggle" "$action" \
"status" "刷新/查看状态" \
"install" "安装/检查 Tailscale" \
"exit" "退出" 3>&1 1>&2 2>&3)"; then
"exit" "退出")"; then
continue
fi
elif command_exists dialog; then
if ! choice="$(dialog --stdout --no-cancel --title "Tailscale 路由管理器" \
--menu "$(get_status_text tui)\n\n请选择操作:" 30 78 6 \
elif command_exists whiptail; then
if ! choice="$(whiptail --nocancel --title "Tailscale 路由管理器" \
--menu "$(get_status_text whiptail)\n\n请选择操作:" 30 78 6 \
"toggle" "$action" \
"status" "刷新/查看状态" \
"install" "安装/检查 Tailscale" \
"exit" "退出")"; then
"exit" "退出" 3>&1 1>&2 2>&3)"; then
continue
fi
else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment