feat: add note mode and workflow config

This commit is contained in:
shiyue
2026-06-12 16:39:44 +08:00
parent 5308a10b52
commit 8b2173be8f
93 changed files with 15292 additions and 50 deletions

190
start.sh
View File

@@ -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