chore: remove confirmed stale workspace artifacts

This commit is contained in:
Albert 2026-04-26 09:22:11 +08:00
parent 1d34e32788
commit d5e76d67d2
16 changed files with 0 additions and 3563 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

1237
ai.rtf

File diff suppressed because it is too large Load Diff

View File

@ -1,105 +0,0 @@
#!/bin/bash
# Cloudflare Tunnel Setup Script for PMFlow
set -e
echo "🚀 Starting Cloudflare Tunnel Setup..."
# Check if cloudflared is installed
if ! command -v cloudflared &> /dev/null; then
echo "❌ cloudflared is not installed. Please install it first:"
echo " brew install cloudflared"
exit 1
fi
# Ask for configuration
read -p "Enter your Frontend domain (e.g., pmflow.com): " FRONTEND_DOMAIN
read -p "Enter your Backend domain (e.g., api.pmflow.com): " BACKEND_DOMAIN
read -p "Enter a name for your tunnel (e.g., pmflow-tunnel): " TUNNEL_NAME
if [ -z "$FRONTEND_DOMAIN" ] || [ -z "$BACKEND_DOMAIN" ] || [ -z "$TUNNEL_NAME" ]; then
echo "❌ Frontend domain, Backend domain, and Tunnel name are required."
exit 1
fi
echo "Checking authentication..."
# Check if cert.pem exists in default location
if [ ! -f "$HOME/.cloudflared/cert.pem" ]; then
echo "⚠️ You need to login to Cloudflare first."
cloudflared tunnel login
fi
echo "Creating tunnel '$TUNNEL_NAME'..."
# Check if tunnel exists, if not create it
if ! cloudflared tunnel list | grep -q "$TUNNEL_NAME"; then
cloudflared tunnel create "$TUNNEL_NAME"
else
echo "ℹ️ Tunnel '$TUNNEL_NAME' already exists."
fi
echo "Routing DNS..."
# Route DNS for both domains
cloudflared tunnel route dns "$TUNNEL_NAME" "$FRONTEND_DOMAIN"
cloudflared tunnel route dns "$TUNNEL_NAME" "$BACKEND_DOMAIN"
# Get Tunnel ID
TUNNEL_ID=$(cloudflared tunnel list | grep "$TUNNEL_NAME" | awk '{print $1}')
if [ -z "$TUNNEL_ID" ]; then
echo "❌ Could not find Tunnel ID for '$TUNNEL_NAME'"
exit 1
fi
echo "Generating config file..."
# Create config.yml
mkdir -p devops/tunnel
cat > devops/tunnel/config.yml <<EOF
tunnel: $TUNNEL_ID
credentials-file: $HOME/.cloudflared/$TUNNEL_ID.json
ingress:
- hostname: $FRONTEND_DOMAIN
service: http://localhost:5174
- hostname: $BACKEND_DOMAIN
service: http://localhost:8000
- service: http_status:404
EOF
echo "✅ Tunnel configuration created at devops/tunnel/config.yml"
# Update .env file in frontend
ENV_FILE="frontend/.env"
if [ ! -f "$ENV_FILE" ]; then
touch "$ENV_FILE"
fi
# Update VITE_APP_DOMAIN and VITE_API_BASE_URL
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s|VITE_APP_DOMAIN=.*|VITE_APP_DOMAIN=$FRONTEND_DOMAIN|" "$ENV_FILE"
# Check if VITE_API_BASE_URL exists, if so replace it, else append
if grep -q "VITE_API_BASE_URL=" "$ENV_FILE"; then
sed -i '' "s|VITE_API_BASE_URL=.*|VITE_API_BASE_URL=https://$BACKEND_DOMAIN|" "$ENV_FILE"
else
echo "VITE_API_BASE_URL=https://$BACKEND_DOMAIN" >> "$ENV_FILE"
fi
else
sed -i "s|VITE_APP_DOMAIN=.*|VITE_APP_DOMAIN=$FRONTEND_DOMAIN|" "$ENV_FILE"
if grep -q "VITE_API_BASE_URL=" "$ENV_FILE"; then
sed -i "s|VITE_API_BASE_URL=.*|VITE_API_BASE_URL=https://$BACKEND_DOMAIN|" "$ENV_FILE"
else
echo "VITE_API_BASE_URL=https://$BACKEND_DOMAIN" >> "$ENV_FILE"
fi
fi
if ! grep -q "VITE_APP_DOMAIN=" "$ENV_FILE"; then
echo "VITE_APP_DOMAIN=$FRONTEND_DOMAIN" >> "$ENV_FILE"
fi
echo "✅ Updated $ENV_FILE with:"
echo " VITE_APP_DOMAIN=$FRONTEND_DOMAIN"
echo " VITE_API_BASE_URL=https://$BACKEND_DOMAIN"
echo "🎉 Setup complete! You can now run the tunnel with:"
echo " ./devops/tunnel/start.sh"

View File

@ -1,135 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# PMFlow 公网穿透启动器(保留为唯一 tunnel 入口)
# 优先命名隧道;未配置时自动退回 quick tunnel。
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd -- "${SCRIPT_DIR}/../.." && pwd)"
CONFIG_FILE="${SCRIPT_DIR}/config.yml"
SETUP_SCRIPT="${SCRIPT_DIR}/setup.sh"
LOG_DIR="${ROOT_DIR}/logs"
FRONTEND_PORT="${PMFLOW_TUNNEL_FRONTEND_PORT:-${FRONTEND_PORT:-5174}}"
BACKEND_PORT="${PMFLOW_TUNNEL_BACKEND_PORT:-${BACKEND_PORT:-8000}}"
TUNNEL_PROTOCOL="${PMFLOW_TUNNEL_PROTOCOL:-quic}"
HEALTH_RETRIES="${PMFLOW_TUNNEL_HEALTH_RETRIES:-3}"
FOREGROUND="${PMFLOW_TUNNEL_FOREGROUND:-1}"
FRONT_LOG="${LOG_DIR}/tunnel-frontend.log"
BACK_LOG="${LOG_DIR}/tunnel-backend.log"
extract_url() {
local logfile="$1"
grep -aEo 'https://[-a-z0-9]+\.trycloudflare\.com' "$logfile" 2>/dev/null | tail -1
}
wait_for_url() {
local logfile="$1"
local retries="${2:-30}"
local i=1
local url=""
while [ "$i" -le "$retries" ]; do
url="$(extract_url "$logfile")"
if [ -n "$url" ]; then
echo "$url"
return 0
fi
sleep 1
i=$((i + 1))
done
return 1
}
check_url() {
local url="$1"
local max_retry="$2"
local retry=1
while [ "$retry" -le "$max_retry" ]; do
if curl -kfsS --max-time 8 "$url" >/dev/null 2>&1; then
return 0
fi
sleep 2
retry=$((retry + 1))
done
return 1
}
run_quick_tunnels() {
mkdir -p "$LOG_DIR"
pkill -f "cloudflared tunnel .*127\\.0\\.0\\.1:${FRONTEND_PORT}" >/dev/null 2>&1 || true
pkill -f "cloudflared tunnel .*127\\.0\\.0\\.1:${BACKEND_PORT}" >/dev/null 2>&1 || true
echo "🚀 启动临时隧道..."
echo "📂 日志目录: ${LOG_DIR}"
echo "🌐 前端隧道: 127.0.0.1:${FRONTEND_PORT}"
cloudflared tunnel --protocol "${TUNNEL_PROTOCOL}" --url "http://127.0.0.1:${FRONTEND_PORT}" >"$FRONT_LOG" 2>&1 &
local front_pid=$!
echo "🌐 后端隧道: 127.0.0.1:${BACKEND_PORT}"
cloudflared tunnel --protocol "${TUNNEL_PROTOCOL}" --url "http://127.0.0.1:${BACKEND_PORT}" >"$BACK_LOG" 2>&1 &
local back_pid=$!
echo "⏳ 等待隧道地址..."
local front_url=""
local back_url=""
front_url="$(wait_for_url "$FRONT_LOG" 45 || true)"
back_url="$(wait_for_url "$BACK_LOG" 45 || true)"
if [ -z "$front_url" ] || [ -z "$back_url" ]; then
echo "❌ 未获取到公网地址。"
echo " 前端日志: $FRONT_LOG"
echo " 后端日志: $BACK_LOG"
tail -n 20 "$FRONT_LOG" || true
tail -n 20 "$BACK_LOG" || true
kill "$front_pid" "$back_pid" >/dev/null 2>&1 || true
return 1
fi
local front_ok=false
local back_ok=false
if check_url "${front_url}/login" "$HEALTH_RETRIES" || check_url "${front_url}" "$HEALTH_RETRIES"; then
front_ok=true
fi
if check_url "${back_url}/healthz" "$HEALTH_RETRIES"; then
back_ok=true
fi
if [ "$front_ok" = true ] && [ "$back_ok" = true ]; then
echo "✅ 隧道连通成功"
else
echo "⚠️ 隧道已启动,但健康检查未全部通过(可稍后重试)"
fi
echo "----------------------------------------"
echo "前端: ${front_url}"
echo "后端: ${back_url}"
echo "----------------------------------------"
echo "ℹ️ 停止命令: pkill -f \"cloudflared tunnel\""
if [ "$FOREGROUND" != "1" ]; then
echo "✅ 已切到后台运行"
echo " 前端 PID: ${front_pid}"
echo " 后端 PID: ${back_pid}"
return 0
fi
cleanup() {
echo ""
echo "🔴 tunnel 已关闭"
kill "$front_pid" "$back_pid" >/dev/null 2>&1 || true
}
trap cleanup EXIT INT TERM
wait "$front_pid" "$back_pid"
}
echo "🚀 启动公网穿透..."
if [ -f "$CONFIG_FILE" ]; then
echo "✅ 检测到命名隧道配置: ${CONFIG_FILE}"
echo "🌐 使用命名隧道运行(前台)"
exec cloudflared tunnel run --config "$CONFIG_FILE"
fi
echo "⚠️ 未检测到命名隧道配置,自动切换临时隧道。"
echo " 若需固定域名,请先执行: ${SETUP_SCRIPT}"
run_quick_tunnels

View File

@ -1,340 +0,0 @@
#!/usr/bin/env bash
set -uo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$PROJECT_DIR"
mkdir -p logs
PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:${PATH:-}"
URL_PATTERN='https://[a-z0-9-]+\.trycloudflare\.com'
WATCH_LOG="logs/tunnel-frontend-watch.log"
WATCH_STDOUT_LOG="logs/tunnel-frontend-watch.stdout"
WATCH_PID_FILE="logs/tunnel-frontend-watch.pid"
RUN_LOG="logs/tunnel-frontend.log"
TUNNEL_PID_FILE="logs/tunnel-frontend.pid"
PUBLIC_URL_FILE="logs/public_url.txt"
ACTIVE_CHILD_PID=""
is_pid_running() {
local pid="${1:-}"
[[ -n "$pid" ]] || return 1
ps -p "$pid" >/dev/null 2>&1
}
log_watch() {
local message="$1"
local line="[$(date '+%Y-%m-%d %H:%M:%S')] [watch] ${message}"
printf '%s\n' "$line" | tee -a "$WATCH_LOG"
}
log_watch_err() {
local message="$1"
local line="[$(date '+%Y-%m-%d %H:%M:%S')] [watch] ${message}"
printf '%s\n' "$line" | tee -a "$WATCH_LOG" >&2
}
read_frontend_url() {
local line=""
line="$(rg '^frontend=' "$PUBLIC_URL_FILE" 2>/dev/null | tail -n 1 || true)"
if [[ -n "$line" ]]; then
echo "${line#frontend=}"
return 0
fi
sed -n '1p' "$PUBLIC_URL_FILE" 2>/dev/null | rg '^https?://' -N || true
}
read_backend_url() {
local line=""
line="$(rg '^backend=' "$PUBLIC_URL_FILE" 2>/dev/null | tail -n 1 || true)"
if [[ -n "$line" ]]; then
echo "${line#backend=}"
return 0
fi
sed -n '2p' "$PUBLIC_URL_FILE" 2>/dev/null | rg '^https?://' -N || true
}
write_frontend_url() {
local frontend_url="$1"
local backend_url=""
backend_url="$(read_backend_url)"
: > "$PUBLIC_URL_FILE"
echo "frontend=$frontend_url" >> "$PUBLIC_URL_FILE"
if [[ -n "$backend_url" ]]; then
echo "backend=$backend_url" >> "$PUBLIC_URL_FILE"
fi
}
find_cloudflared_bin() {
local bin
bin="$(command -v cloudflared || true)"
if [[ -n "$bin" ]]; then
echo "$bin"
return 0
fi
for candidate in /opt/homebrew/bin/cloudflared /usr/local/bin/cloudflared; do
if [[ -x "$candidate" ]]; then
echo "$candidate"
return 0
fi
done
echo ""
}
extract_tunnel_url() {
local logfile="$1"
rg -o "$URL_PATTERN" "$logfile" 2>/dev/null \
| rg -v "^https://api\\.trycloudflare\\.com$" \
| tail -n 1
}
probe_local_origin() {
local port="$1"
local code=""
code="$(curl --noproxy '*' -s -m 3 -o /dev/null -w "%{http_code}" "http://127.0.0.1:${port}/" || true)"
[[ "$code" =~ ^[0-9]{3}$ ]] || return 1
[[ "$code" -ge 200 && "$code" -lt 500 ]]
}
probe_tunnel_url() {
local url="$1"
local code=""
code="$(curl --noproxy '*' -s -m 8 -o /dev/null -w "%{http_code}" "${url}/" || true)"
[[ "$code" =~ ^[0-9]{3}$ ]] || return 1
[[ "$code" -ge 200 && "$code" -lt 500 ]]
}
probe_tunnel_url_stable() {
local url="$1"
local checks="${2:-2}"
local current=1
while [[ "$current" -le "$checks" ]]; do
probe_tunnel_url "$url" || return 1
if [[ "$current" -lt "$checks" ]]; then
sleep 1
fi
current=$((current + 1))
done
}
resolve_frontend_port() {
local preferred="${PMFLOW_FRONTEND_TUNNEL_PORT:-${FRONTEND_PORT:-5174}}"
local candidates=("$preferred" 5174 5175 5176 5177 5178)
local seen=" "
local port=""
for port in "${candidates[@]}"; do
[[ "$seen" == *" ${port} "* ]] && continue
seen="${seen}${port} "
if probe_local_origin "$port"; then
echo "$port"
return 0
fi
done
echo "$preferred"
}
is_watch_running() {
if [[ ! -f "$WATCH_PID_FILE" ]]; then
return 1
fi
local pid
pid="$(cat "$WATCH_PID_FILE" 2>/dev/null || true)"
if [[ -z "$pid" ]]; then
return 1
fi
if ps -p "$pid" >/dev/null 2>&1; then
return 0
fi
return 1
}
cleanup_children() {
if [[ -n "${ACTIVE_CHILD_PID:-}" ]] && is_pid_running "$ACTIVE_CHILD_PID"; then
kill "$ACTIVE_CHILD_PID" >/dev/null 2>&1 || true
fi
if [[ -f "$TUNNEL_PID_FILE" ]]; then
local pid
pid="$(cat "$TUNNEL_PID_FILE" 2>/dev/null || true)"
if [[ -n "$pid" ]] && is_pid_running "$pid"; then
kill "$pid" >/dev/null 2>&1 || true
fi
fi
}
stop_watch() {
local stopped=0
if [[ -f "$WATCH_PID_FILE" ]]; then
local wpid
wpid="$(cat "$WATCH_PID_FILE" 2>/dev/null || true)"
if [[ -n "$wpid" ]] && is_pid_running "$wpid"; then
kill "$wpid" >/dev/null 2>&1 || true
stopped=1
fi
fi
cleanup_children
rm -f "$WATCH_PID_FILE" "$TUNNEL_PID_FILE"
if [[ "$stopped" -eq 1 ]]; then
echo "[前端隧道守护] 已停止"
else
echo "[前端隧道守护] 未运行"
fi
}
print_status() {
local tunnel_pid=""
if [[ -f "$TUNNEL_PID_FILE" ]]; then
tunnel_pid="$(cat "$TUNNEL_PID_FILE" 2>/dev/null || true)"
fi
if is_watch_running; then
local wpid cpid
wpid="$(cat "$WATCH_PID_FILE" 2>/dev/null || true)"
cpid="${tunnel_pid:-$(cat "$TUNNEL_PID_FILE" 2>/dev/null || true)}"
echo "[前端隧道守护] 运行中 watch_pid=${wpid:-unknown} tunnel_pid=${cpid:-unknown}"
else
echo "[前端隧道守护] 未运行"
fi
local frontend_url backend_url
frontend_url="$(read_frontend_url)"
backend_url="$(read_backend_url)"
if [[ -n "$frontend_url" ]]; then
echo "前端地址: $frontend_url"
if is_pid_running "$tunnel_pid"; then
echo "前端健康: tunnel进程运行中"
else
echo "前端健康: tunnel进程未运行"
fi
else
echo "前端地址: (空)"
fi
if [[ -n "$backend_url" ]]; then
echo "后端地址: $backend_url"
else
echo "后端地址: (未配置/未暴露)"
fi
}
start_watch_background() {
if is_watch_running; then
print_status
return 0
fi
nohup bash "$0" run >"$WATCH_STDOUT_LOG" 2>&1 &
local pid="$!"
echo "$pid" >"$WATCH_PID_FILE"
echo "[前端隧道守护] 已启动 pid=$pid"
sleep 1
tail -n 5 "$WATCH_STDOUT_LOG" 2>/dev/null || true
}
run_watch_loop() {
local cf_bin
cf_bin="$(find_cloudflared_bin)"
if [[ -z "$cf_bin" ]]; then
log_watch_err "cloudflared_not_found"
exit 1
fi
echo "$$" >"$WATCH_PID_FILE"
log_watch "start bin=$cf_bin"
trap 'cleanup_children; rm -f "$WATCH_PID_FILE"; log_watch "exit code=$?"' EXIT INT TERM
while true; do
local frontend_port tunnel_protocol child_pid published current_url url
local strict_public_health public_health_interval public_health_failure_threshold
local unhealthy_count last_health_check_at
frontend_port="$(resolve_frontend_port)"
tunnel_protocol="${PMFLOW_TUNNEL_PROTOCOL_FRONTEND:-${PMFLOW_TUNNEL_PROTOCOL:-http2}}"
strict_public_health="${PMFLOW_TUNNEL_STRICT_PUBLIC_HEALTH:-0}"
public_health_interval="${PMFLOW_TUNNEL_PUBLIC_HEALTH_INTERVAL_SECONDS:-30}"
public_health_failure_threshold="${PMFLOW_TUNNEL_PUBLIC_HEALTH_FAILURE_THRESHOLD:-5}"
: > "$RUN_LOG"
log_watch "origin=http://127.0.0.1:${frontend_port} protocol=${tunnel_protocol}"
env -u HTTPS_PROXY -u HTTP_PROXY -u ALL_PROXY -u https_proxy -u http_proxy -u all_proxy \
NO_PROXY="*" \
"$cf_bin" tunnel --protocol "$tunnel_protocol" --url "http://127.0.0.1:${frontend_port}" >"$RUN_LOG" 2>&1 &
child_pid="$!"
ACTIVE_CHILD_PID="$child_pid"
echo "$child_pid" > "$TUNNEL_PID_FILE"
published="0"
current_url=""
for _ in {1..90}; do
url="$(extract_tunnel_url "$RUN_LOG" || true)"
if [[ -n "$url" ]]; then
if [[ "$strict_public_health" == "1" ]] && ! probe_tunnel_url_stable "$url"; then
:
else
if [[ "$url" != "$current_url" ]]; then
write_frontend_url "$url"
log_watch "url=$url"
fi
current_url="$url"
published="1"
break
fi
fi
if ! is_pid_running "$child_pid"; then
break
fi
sleep 1
done
unhealthy_count=0
last_health_check_at=0
while is_pid_running "$child_pid"; do
if [[ "$strict_public_health" == "1" && "$published" == "1" && -n "$current_url" ]]; then
if (( $(date +%s) - last_health_check_at >= public_health_interval )); then
last_health_check_at="$(date +%s)"
if probe_tunnel_url "$current_url"; then
unhealthy_count=0
else
unhealthy_count=$((unhealthy_count + 1))
log_watch_err "health_check_failed url=${current_url} count=${unhealthy_count}"
fi
if [[ "$unhealthy_count" -ge "$public_health_failure_threshold" ]]; then
log_watch_err "url_unhealthy_restart url=${current_url}"
kill "$child_pid" >/dev/null 2>&1 || true
break
fi
fi
fi
sleep 5
done
wait "$child_pid" || true
ACTIVE_CHILD_PID=""
if [[ "$published" != "1" ]]; then
log_watch_err "exited_before_url"
else
log_watch_err "exited_restart"
fi
sleep 2
done
}
cmd="${1:-run}"
case "$cmd" in
run)
run_watch_loop
;;
start)
start_watch_background
;;
stop)
stop_watch
;;
status)
print_status
;;
url)
front="$(read_frontend_url)"
back="$(read_backend_url)"
echo "前端地址: ${front:-未就绪}"
echo "后端地址: ${back:-未配置/未暴露}"
;;
*)
echo "Usage: $0 {run|start|stop|status|url}"
exit 1
;;
esac

Binary file not shown.

Binary file not shown.

View File

@ -1,36 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>短确认验收结果</title>
<style>
body { font-family: Menlo, Monaco, 'SF Mono', monospace; background:#f6f7f9; margin:24px; }
.card { background:#fff; border:1px solid #d9dde3; border-radius:10px; padding:16px; }
h1 { margin:0 0 10px 0; font-size:20px; }
p { margin:6px 0; font-size:13px; }
.bad { color:#b42318; font-weight:700; }
.ok { color:#027a48; font-weight:700; }
pre { background:#f8fafc; border:1px solid #e4e7ec; border-radius:8px; padding:10px; white-space:pre-wrap; word-break:break-word; font-size:12px; }
</style>
</head>
<body>
<div class="card">
<h1>短确认重设计验收(消息1写操作场景)</h1>
<p>消息1 ID: accept-shortconfirm-redesign-msg1-1773935717</p>
<p>消息2 ID: accept-shortconfirm-redesign-msg2-1773935717</p>
<p>消息1 intent: <span class="bad">query.answer</span>(预期 signal.create)</p>
<p>消息2 context_source: <span class="ok">session_inherited</span></p>
<p>消息2 intent: <span class="bad">query.answer</span>(继承了消息1的查询意图)</p>
<p>消息2 classify_intent_ai_pmo_kernel 调用: <span class="ok">无</span></p>
<p>消息2 LLM 调用: <span class="bad">有</span>(adaptive_rag_answer_normal)</p>
<pre>ai_call_logs:
1932 classify_intent_ai_pmo_kernel hit_msg1=1 hit_msg2=0
1933 adaptive_rag_answer_normal hit_msg1=1 hit_msg2=0
1934 adaptive_rag_answer_normal hit_msg1=0 hit_msg2=1
work_items:
397 source=msg1 state=failed intent=query.answer context_source=llm_only
398 source=msg2 state=succeeded intent=query.answer context_source=session_inherited</pre>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.