feat: 工作台外壳重构 + /home 改为智能助手 + 产品更名

前端
- MainLayout: 移除顶部标题栏,Workspace Tabs 提至最顶层,通知铃随行
- 账号入口由右上角移至左下角侧边栏底部(下拉:我的资料 / 退出登录),
  折叠态仅保留头像
- /home 现渲染智能助手并作为其规范 URL;/tools/smart-assistant 保留为重定向别名
- 工作台总览移至 /overview,侧边栏入口同步调整
- workbench store: 新增 tab 归一化,迁移已持久化的旧标签与旧路由
- 智能助手欢迎语改为「我 Bosheng 数字员工,我帮你」
- 最佳实践卡片: 4 张减为 3 张,图片块高度减半(aspect-ratio 4/3 → 8/3)

产品更名
- 后端 system prompt、CLAUDE.md、PROJECT_STATE.md 及设计文档:
  博昇内部培训平台 → EAI 数字员工平台

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
eaiadmin
2026-09-14 08:19:42 +08:00
co-authored by Claude Code
parent 5c0870af97
commit 95fcf161b0
21 changed files with 999 additions and 1176 deletions
+116 -11
View File
@@ -14,6 +14,7 @@ set -euo pipefail
FORCE=0
SKIP_PREFLIGHT=0
SKIP_SMOKE=0
SKIP_BUILD=0
while [[ $# -gt 0 ]]; do
case "$1" in
@@ -26,14 +27,20 @@ while [[ $# -gt 0 ]]; do
--skip-smoke)
SKIP_SMOKE=1
;;
--skip-build)
SKIP_BUILD=1
;;
--help|-h)
cat <<'EOF'
Usage: ./start_dev_10231_10232.sh [options]
Options:
--force Kill processes occupying the frontend/backend ports
--force Kill whatever holds the ports, even non-project processes
(a previous run of this script is always stopped and
replaced automatically)
--skip-preflight Skip preflight checks
--skip-smoke Skip admin account smoke login
--skip-build Do not rebuild the backend, even if sources are newer
--help Show this help
EOF
exit 0
@@ -46,7 +53,6 @@ EOF
shift
done
OURS=(eai_agentplatform-server node npm vite)
BACKEND_PORT=10232
FRONTEND_PORT=10231
@@ -129,10 +135,58 @@ port_pids() {
return 1
}
# Decide whether a process belongs to this project.
#
# This must look at the full command line, not `ps -o comm=`: comm is capped at
# 15 characters (the kernel's TASK_COMM_LEN), so the backend reports itself as
# "eai_agentplatfo" and could never match its own name. That made the launcher
# treat its own backend as a foreign process and refuse to restart.
process_is_ours() {
local pid="$1"
local port="$2"
local args
args="$(ps -o args= -p "$pid" 2>/dev/null || true)"
[[ -z "$args" ]] && return 1
[[ "$args" == *"$BACKEND_BIN"* ]] && return 0
[[ "$args" == *vite* && "$args" == *"--port $port"* ]] && return 0
return 1
}
process_label() {
local pid="$1"
local args
args="$(ps -o args= -p "$pid" 2>/dev/null || true)"
if [[ -z "$args" ]]; then
printf 'unknown'
return 0
fi
args="${args%% *}"
printf '%s' "${args##*/}"
}
# Stop the run recorded by a previous invocation. Uses the pid files so a
# previous instance still gets cleaned up even if it is not holding its port.
kill_previous_run() {
local pid_file="$1"
local port="$2"
local label="$3"
local pid
[[ -f "$pid_file" ]] || return 0
pid="$(cat "$pid_file" 2>/dev/null || true)"
[[ "$pid" =~ ^[0-9]+$ ]] || return 0
kill -0 "$pid" 2>/dev/null || return 0
process_is_ours "$pid" "$port" || return 0
printf ' [.] stopping previous %s (PID %s)\n' "$label" "$pid"
kill "$pid" 2>/dev/null || true
sleep 1
kill -9 "$pid" 2>/dev/null || true
return 0
}
resolve_port() {
local port="$1"
local label="$2"
local pids raw_comm
local pids
mapfile -t pids < <(port_pids "$port" || true)
if [[ ${#pids[@]} -eq 0 ]]; then
printf ' [.] %s :%s free\n' "$label" "$port"
@@ -141,20 +195,18 @@ resolve_port() {
printf ' [!] %s :%s in use by ' "$label" "$port"
for pid in "${pids[@]}"; do
raw_comm="$(ps -p "$pid" -o comm= 2>/dev/null | xargs || echo unknown)"
printf '%s(PID %s) ' "$raw_comm" "$pid"
printf '%s(PID %s) ' "$(process_label "$pid")" "$pid"
done
printf '\n'
for pid in "${pids[@]}"; do
raw_comm="$(ps -p "$pid" -o comm= 2>/dev/null | xargs || echo unknown)"
if [[ "$FORCE" -eq 1 || " ${OURS[*]} " == *" $raw_comm "* ]]; then
printf ' killing %s(PID %s)\n' "$raw_comm" "$pid"
if [[ "$FORCE" -eq 1 ]] || process_is_ours "$pid" "$port"; then
printf ' killing previous %s(PID %s)\n' "$(process_label "$pid")" "$pid"
kill "$pid" 2>/dev/null || true
sleep 1
kill -9 "$pid" 2>/dev/null || true
else
printf ' keeping non-project process: %s(PID %s)\n' "$raw_comm" "$pid"
printf ' keeping non-project process: %s(PID %s)\n' "$(process_label "$pid")" "$pid"
printf ' fix: stop that process manually, or rerun with --force\n'
return 1
fi
@@ -170,6 +222,40 @@ resolve_port() {
return 0
}
# True when the backend binary is missing or older than its sources.
#
# Preflight only proves the binary exists, which happily launches stale code
# after a source edit — the failure is silent, so it needs an explicit check.
backend_needs_build() {
[[ -f "$BACKEND_BIN" ]] || return 0
local newer
newer="$(find "$BACKEND_DIR" -name '*.go' -newer "$BACKEND_BIN" -print -quit 2>/dev/null || true)"
[[ -n "$newer" ]] && return 0
local f
for f in "$BACKEND_DIR/go.mod" "$BACKEND_DIR/go.sum"; do
[[ -f "$f" && "$f" -nt "$BACKEND_BIN" ]] && return 0
done
return 1
}
build_backend() {
local build_log="$DEBUG_LOG_DIR/backend_build.log"
if ! command -v go >/dev/null 2>&1; then
printf ' [FAIL] backend sources changed, but go is not on PATH\n'
printf ' fix: install go, or rebuild manually then rerun with --skip-build\n'
return 1
fi
printf ' [.] backend sources newer than binary, rebuilding ...'
if ( cd "$BACKEND_DIR" && go build -o bin/eai_agentplatform-server ./cmd/server ) >"$build_log" 2>&1; then
printf ' OK\n'
return 0
fi
printf ' FAIL\n'
printf ' log : %s\n' "$build_log"
tail -n 20 "$build_log" 2>/dev/null | sed 's/^/ /' || true
return 1
}
cleanup_started() {
if [[ -f "$BACKEND_PID_FILE" ]]; then
kill "$(cat "$BACKEND_PID_FILE")" 2>/dev/null || true
@@ -198,7 +284,6 @@ if [[ "$SKIP_PREFLIGHT" -eq 0 ]]; then
echo "[1/4] preflight checks"
all_ok=1
check "backend dir exists" "run from repo root" test -d "$BACKEND_DIR" || all_ok=0
check "backend binary built" "cd backend-go && go build ./cmd/server" test -f "$BACKEND_BIN" || all_ok=0
check "frontend dir exists" "run from repo root" test -d "$FRONTEND_DIR" || all_ok=0
check "frontend node_modules" "run npm install in frontend/" test -e "$FRONTEND_DIR/node_modules" || all_ok=0
check "node on PATH" "install nodejs" command -v node || all_ok=0
@@ -215,7 +300,27 @@ else
echo
fi
# Runs whether or not preflight did: a stale binary is a silent failure, and
# building before the old services are stopped means a compile error leaves the
# currently running stack untouched.
if [[ "$SKIP_BUILD" -eq 1 ]]; then
echo "[1/4] backend build check skipped (--skip-build)"
echo
elif backend_needs_build; then
if ! build_backend; then
echo
echo "[ABORT] backend build failed; services left as they were."
exit 1
fi
echo
else
echo "[1/4] backend binary up to date"
echo
fi
echo "[2/4] port conflict check"
kill_previous_run "$BACKEND_PID_FILE" "$BACKEND_PORT" "backend"
kill_previous_run "$FRONTEND_PID_FILE" "$FRONTEND_PORT" "frontend"
resolve_port "$BACKEND_PORT" "backend" || exit 1
resolve_port "$FRONTEND_PORT" "frontend" || exit 1
echo
@@ -279,7 +384,7 @@ echo "================================================================="
echo
trap - EXIT
echo "Usage: ./start_dev_10231_10232.sh [--force] [--skip-preflight]"
echo "Usage: ./start_dev_10231_10232.sh [--force] [--skip-preflight] [--skip-build]"
echo " env: EAI_DEV_BIND_HOST=0.0.0.0 (listen all)"
echo " env: EAI_DEV_PUBLIC_HOST=x.x.x.x (public url)"
echo