diff --git a/Bookworm-OneClick-Mac.sh b/Bookworm-OneClick-Mac.sh index 264492a..cc760de 100644 --- a/Bookworm-OneClick-Mac.sh +++ b/Bookworm-OneClick-Mac.sh @@ -277,7 +277,7 @@ if ! grep -q "$ALIAS_MARKER" "$SHELL_RC" 2>/dev/null; then # Bookworm Portable aliases alias bw='cd ~/bookworm-boot && NO_PROXY="bww.letcareme.com,code.letcareme.com,localhost,127.0.0.1" claude' -alias bw-update='cd ~/bookworm-boot && git pull && echo "Updated!"' +alias bw-update='cd ~/bookworm-boot && git pull && cd ~/.claude && git pull && echo "Updated!"' ALIASES success "已添加到 $SHELL_RC:" info " bw — 启动 Bookworm" diff --git a/Bookworm-Setup.sh b/Bookworm-Setup.sh index 4cb5f88..58a735a 100644 --- a/Bookworm-Setup.sh +++ b/Bookworm-Setup.sh @@ -198,11 +198,73 @@ for d in debug sessions cache backups telemetry memory projects; do done # ============================================================ -# Step 4: 解密凭证 +# Step 4: 解密凭证 (含 Keychain 本日免密) # ============================================================ step 4 "解密凭证" -if [ -f "$SECRETS_ENC" ] && [ -n "$OPENSSL_CMD" ]; then +# Keychain 缓存相关 +KEYCHAIN_SERVICE="bookworm-secrets" +KEYCHAIN_ACCOUNT="$(whoami)" +CACHE_LOADED=false + +# 尝试从 Keychain 加载缓存 +load_cached_secrets() { + local cached + cached=$(security find-generic-password -s "$KEYCHAIN_SERVICE" -a "$KEYCHAIN_ACCOUNT" -w 2>/dev/null) || return 1 + # 检查是否过期 (缓存格式: EXPIRY=ISO日期\nKEY=VALUE\n...) + local expiry + expiry=$(echo "$cached" | head -1) + local expiry_date="${expiry#EXPIRY=}" + local today + today=$(date +%Y-%m-%d) + if [ "$expiry_date" != "$today" ]; then + # 已过期,删除缓存 + security delete-generic-password -s "$KEYCHAIN_SERVICE" -a "$KEYCHAIN_ACCOUNT" 2>/dev/null || true + return 1 + fi + # 加载环境变量 (跳过 EXPIRY 行) + local count=0 + while IFS= read -r line; do + [ -z "$line" ] && continue + [[ "$line" == EXPIRY=* ]] && continue + local key="${line%%=*}" + local value="${line#*=}" + key=$(echo "$key" | tr -d ' ') + if [ -n "$key" ] && [ -n "$value" ]; then + export "$key=$value" + count=$((count + 1)) + fi + done <<< "$cached" + if [ $count -gt 0 ] && [ -n "$ANTHROPIC_API_KEY" ]; then + success "从 Keychain 缓存加载 $count 个凭证 (免密)" + CACHE_LOADED=true + return 0 + fi + return 1 +} + +# 保存凭证到 Keychain +save_secrets_to_cache() { + local today + today=$(date +%Y-%m-%d) + local data="EXPIRY=$today" + local env_keys="ANTHROPIC_API_KEY ANTHROPIC_BASE_URL GITHUB_PERSONAL_ACCESS_TOKEN SLACK_BOT_TOKEN ATLASSIAN_API_TOKEN BROWSERBASE_API_KEY FIRECRAWL_API_KEY" + for k in $env_keys; do + local v="${!k}" + if [ -n "$v" ]; then + data="$data +$k=$v" + fi + done + security add-generic-password -s "$KEYCHAIN_SERVICE" -a "$KEYCHAIN_ACCOUNT" -w "$data" -U 2>/dev/null && \ + success "凭证已缓存至今日 23:59 (下次免密)" || \ + warn "Keychain 缓存失败 (不影响使用)" +} + +# 先尝试缓存 +if load_cached_secrets 2>/dev/null; then + : # 缓存加载成功 +elif [ -f "$SECRETS_ENC" ] && [ -n "$OPENSSL_CMD" ]; then DECRYPTED="" for attempt in 1 2 3; do echo "" @@ -222,6 +284,13 @@ if [ -f "$SECRETS_ENC" ] && [ -n "$OPENSSL_CMD" ]; then fi done <<< "$DECRYPTED" DECRYPTED="" + + # 询问是否缓存 + echo "" + read -p " 今日内免密启动? (y/n): " CACHE_CHOICE + if [ "$CACHE_CHOICE" = "y" ] || [ "$CACHE_CHOICE" = "Y" ]; then + save_secrets_to_cache + fi break else if [ $attempt -lt 3 ]; then diff --git a/quick-reference.txt b/quick-reference.txt index 20f5965..39c3fce 100644 --- a/quick-reference.txt +++ b/quick-reference.txt @@ -47,7 +47,7 @@ # [1/6] 前置检查 (缺依赖自动提示 winget 安装) # [2/6] 代理自动检测 (无需手动找端口) # [3/6] 解密凭证 (输入主密码, 最多3次重试, 可选本日免密) - # [4/6] 同步配置 (git clone 92 Skills / 18 Agents / 29 Hooks) + # [4/6] 同步配置 (git clone 92 Skills / 18 Agents / 34 Hooks) # [5/6] 渲染模板 + 初始化 + Bookworm 完整性验证 + MCP 检查 # [6/6] 启动 Claude Code diff --git a/quick-start.html b/quick-start.html index 75960ec..4c7d043 100644 --- a/quick-start.html +++ b/quick-start.html @@ -74,7 +74,7 @@