feat: add note mode and workflow config
This commit is contained in:
190
start.sh
190
start.sh
@@ -7,6 +7,8 @@ ENTRY_FILE="${CC_WEB_ENTRY:-server.js}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
APP_DIR="${SCRIPT_DIR}"
|
||||
ENTRY_PATH="${APP_DIR}/${ENTRY_FILE}"
|
||||
ENV_FILE="${APP_DIR}/.env"
|
||||
ENV_EXAMPLE_FILE="${APP_DIR}/.env.example"
|
||||
|
||||
log() {
|
||||
printf '[cc-web pm2] %s\n' "$*"
|
||||
@@ -25,6 +27,193 @@ ensure_command() {
|
||||
fi
|
||||
}
|
||||
|
||||
get_env_value() {
|
||||
local key="$1"
|
||||
[[ -f "${ENV_FILE}" ]] || return 0
|
||||
|
||||
awk -v key="${key}" '
|
||||
$0 ~ /^[[:space:]]*#/ { next }
|
||||
{
|
||||
line = $0
|
||||
sub(/^[[:space:]]*/, "", line)
|
||||
if (index(line, key "=") == 1) {
|
||||
sub(/^[^=]*=/, "", line)
|
||||
print line
|
||||
exit
|
||||
}
|
||||
}
|
||||
' "${ENV_FILE}"
|
||||
}
|
||||
|
||||
set_env_value() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
local tmp_file
|
||||
tmp_file="$(mktemp)"
|
||||
|
||||
if [[ -f "${ENV_FILE}" ]]; then
|
||||
awk -v key="${key}" -v value="${value}" '
|
||||
BEGIN { updated = 0 }
|
||||
{
|
||||
line = $0
|
||||
sub(/^[[:space:]]*/, "", line)
|
||||
if (index(line, key "=") == 1) {
|
||||
print key "=" value
|
||||
updated = 1
|
||||
next
|
||||
}
|
||||
print
|
||||
}
|
||||
END {
|
||||
if (!updated) print key "=" value
|
||||
}
|
||||
' "${ENV_FILE}" > "${tmp_file}"
|
||||
else
|
||||
printf '%s=%s\n' "${key}" "${value}" > "${tmp_file}"
|
||||
fi
|
||||
|
||||
mv "${tmp_file}" "${ENV_FILE}"
|
||||
chmod 600 "${ENV_FILE}"
|
||||
}
|
||||
|
||||
validate_password() {
|
||||
local password="$1"
|
||||
local types=0
|
||||
|
||||
if [[ "${#password}" -lt 8 ]]; then
|
||||
printf '密码长度至少 8 位\n'
|
||||
return 1
|
||||
fi
|
||||
|
||||
[[ "${password}" =~ [a-z] ]] && types=$((types + 1))
|
||||
[[ "${password}" =~ [A-Z] ]] && types=$((types + 1))
|
||||
[[ "${password}" =~ [0-9] ]] && types=$((types + 1))
|
||||
[[ "${password}" =~ [^a-zA-Z0-9] ]] && types=$((types + 1))
|
||||
|
||||
if [[ "${types}" -lt 2 ]]; then
|
||||
printf '密码需包含至少 2 种字符类型(大写/小写/数字/特殊字符)\n'
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
resolve_config_dir() {
|
||||
local configured
|
||||
configured="${CC_WEB_CONFIG_DIR:-$(get_env_value CC_WEB_CONFIG_DIR)}"
|
||||
|
||||
if [[ -n "${configured}" ]]; then
|
||||
if [[ "${configured}" = /* ]]; then
|
||||
printf '%s\n' "${configured}"
|
||||
else
|
||||
printf '%s/%s\n' "${APP_DIR}" "${configured}"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
printf '%s/config\n' "${APP_DIR}"
|
||||
}
|
||||
|
||||
ensure_env_file() {
|
||||
if [[ -f "${ENV_FILE}" ]]; then
|
||||
log "检测到 .env 配置文件"
|
||||
chmod 600 "${ENV_FILE}"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -f "${ENV_EXAMPLE_FILE}" ]]; then
|
||||
cp "${ENV_EXAMPLE_FILE}" "${ENV_FILE}"
|
||||
chmod 600 "${ENV_FILE}"
|
||||
log "已从 .env.example 创建 .env"
|
||||
else
|
||||
: > "${ENV_FILE}"
|
||||
chmod 600 "${ENV_FILE}"
|
||||
log "已创建空 .env"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_port_config() {
|
||||
local port
|
||||
port="$(get_env_value PORT)"
|
||||
|
||||
if [[ -z "${port}" ]]; then
|
||||
set_env_value PORT "8002"
|
||||
log "未配置 PORT,已写入默认端口 8002"
|
||||
return
|
||||
fi
|
||||
|
||||
log "服务端口: ${port}"
|
||||
}
|
||||
|
||||
ensure_initial_password() {
|
||||
local config_dir auth_file env_password password confirm message
|
||||
|
||||
config_dir="$(resolve_config_dir)"
|
||||
auth_file="${config_dir}/auth.json"
|
||||
|
||||
if [[ -f "${auth_file}" ]]; then
|
||||
log "检测到已有登录配置: ${auth_file},跳过初始密码设置"
|
||||
return
|
||||
fi
|
||||
|
||||
env_password="$(get_env_value CC_WEB_PASSWORD)"
|
||||
if [[ -n "${env_password}" && "${env_password}" != "changeme" ]]; then
|
||||
log "检测到 .env 已配置 CC_WEB_PASSWORD,首次启动时会迁移到 auth.json"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ! -t 0 ]]; then
|
||||
fail "首次启动缺少初始密码。请在 .env 中设置 CC_WEB_PASSWORD,或在交互终端执行 ./start.sh。"
|
||||
fi
|
||||
|
||||
log "首次启动需要设置 Web 登录初始密码"
|
||||
while true; do
|
||||
read -r -s -p "请输入初始密码: " password
|
||||
printf '\n'
|
||||
read -r -s -p "请再次输入初始密码: " confirm
|
||||
printf '\n'
|
||||
|
||||
if [[ "${password}" != "${confirm}" ]]; then
|
||||
log "两次输入不一致,请重新输入"
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! message="$(validate_password "${password}")"; then
|
||||
log "${message}"
|
||||
continue
|
||||
fi
|
||||
|
||||
set_env_value CC_WEB_PASSWORD "${password}"
|
||||
log "初始密码已写入 .env;服务首次启动后会迁移到 config/auth.json"
|
||||
break
|
||||
done
|
||||
}
|
||||
|
||||
check_agent_cli() {
|
||||
local key="$1"
|
||||
local default_cmd="$2"
|
||||
local label="$3"
|
||||
local configured
|
||||
|
||||
configured="$(get_env_value "${key}")"
|
||||
configured="${configured:-${default_cmd}}"
|
||||
|
||||
if command -v "${configured}" >/dev/null 2>&1; then
|
||||
log "${label} CLI: $(command -v "${configured}")"
|
||||
return
|
||||
fi
|
||||
|
||||
log "未检测到 ${label} CLI (${configured});服务可启动,但对应 Agent 功能需要安装并登录后才能使用"
|
||||
}
|
||||
|
||||
check_runtime_config() {
|
||||
ensure_env_file
|
||||
ensure_port_config
|
||||
ensure_initial_password
|
||||
check_agent_cli CLAUDE_PATH claude "Claude"
|
||||
check_agent_cli CODEX_PATH codex "Codex"
|
||||
}
|
||||
|
||||
install_pm2() {
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
log "PM2 已安装: $(command -v pm2)"
|
||||
@@ -93,6 +282,7 @@ main() {
|
||||
fail "Node.js 版本过低,当前为 $(node -v),要求 >= 18。"
|
||||
fi
|
||||
|
||||
check_runtime_config
|
||||
install_pm2
|
||||
install_dependencies
|
||||
start_or_restart_app
|
||||
|
||||
Reference in New Issue
Block a user