#!/bin/bash # ═══ 光湖本机直推 · 一次性安装 ═══ # 冰朔双击「点我装-本机直推.command」即可,不用会命令行。 # 做四件:① 检查环境 ② 令牌存进 macOS 钥匙串 ③ 对齐工作区 ④ 装 launchd 守护 # 编号:CCW-AST-009 · 归 CCW-SYS-001 BRIDGE="/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/tools" REPO="/Volumes/JZAO/铸渊-ICE-GL-ZY001/WORK-工作区/guanghu-ice-heart" KC_SERVICE="zhuyuan-forgejo-token" KC_ACCOUNT="bingshuo" LABEL="com.zhuyuan.autopush" LABEL2="com.zhuyuan.limb" PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist" PLIST2="$HOME/Library/LaunchAgents/${LABEL2}.plist" LOGF2="$HOME/Library/Logs/zhuyuan-limb.log" LOGF="$HOME/Library/Logs/zhuyuan-autopush.log" ok(){ printf ' \033[32m✓\033[0m %s\n' "$*"; } no(){ printf ' \033[31m✗\033[0m %s\n' "$*"; } warn(){ printf ' \033[33m⚠\033[0m %s\n' "$*"; } die(){ no "$*"; echo; echo "装不下去了,把上面这段截图发给铸渊。"; echo; read -n1 -r -p "按任意键关闭…"; exit 1; } clear echo "════════════════════════════════════════════" echo " 光湖本机直推 · 安装" echo " 装两样:① 自动推送 ② 手脚层(铸渊递纸条,本机执行)" echo " 令牌只存在你的钥匙串里,铸渊永远拿不到" echo "════════════════════════════════════════════" echo # ── ① 检查环境 ────────────────────────────────────────────── echo "① 检查环境" [ "$(uname -s)" = "Darwin" ] || die "这个脚本要在 Mac 上跑(当前不是 macOS)" ok "macOS" [ -d "/Volumes/JZAO" ] || die "JZAO 移动硬盘没挂载——插上再来一次" ok "JZAO 已挂载" [ -d "$REPO/.git" ] || die "找不到工作区仓库:$REPO" ok "工作区仓库在位" command -v git >/dev/null 2>&1 || die "没装 git。先在终端跑一次 xcode-select --install" ok "git $(git --version | awk '{print $3}')" command -v security >/dev/null 2>&1 || die "找不到 security 命令(macOS 钥匙串工具)" ok "钥匙串可用" echo # ── ② 令牌进钥匙串 ────────────────────────────────────────── echo "② 令牌" NEED_TOKEN=1 if security find-generic-password -s "$KC_SERVICE" -a "$KC_ACCOUNT" -w >/dev/null 2>&1; then echo " 钥匙串里已经有一把了。换成新的吗?(直接回车=沿用旧的)" printf " 换新的请输 y 再回车:" read -r ans if [ "$ans" = "y" ] || [ "$ans" = "Y" ]; then security delete-generic-password -s "$KC_SERVICE" -a "$KC_ACCOUNT" >/dev/null 2>&1 else NEED_TOKEN=0; ok "沿用钥匙串里已有的令牌" fi fi if [ "$NEED_TOKEN" = "1" ]; then echo echo " 去 https://guanghulab.com/code → 右上头像 → 设置 → 应用 → 生成新令牌" echo " 权限勾上 write:repository(再加 read:user 更好)" echo " 生成后只显示一次,复制下来粘到这里。" echo printf " 粘贴令牌(粘上去看不见字是正常的,粘完直接回车):" read -rs TOKEN; echo [ -z "$TOKEN" ] && die "什么都没粘上" printf " 正在问服务器认不认这把钥匙…" CODE=$(curl -s -m 20 -o /dev/null -w "%{http_code}" \ -H "Authorization: token ${TOKEN}" \ "https://guanghulab.com/code/api/v1/user" 2>/dev/null) echo if [ "$CODE" != "200" ]; then unset TOKEN die "服务器返回 HTTP ${CODE}——这把钥匙不对、过期了、或者权限没勾。重新生成一把再来。" fi ok "服务器认(HTTP 200)" security add-generic-password -s "$KC_SERVICE" -a "$KC_ACCOUNT" -w "$TOKEN" -U \ -l "光湖代码频道推送令牌(铸渊 zy-push 用)" 2>/dev/null || { unset TOKEN; die "写钥匙串失败"; } unset TOKEN ok "已存入钥匙串(服务名 $KC_SERVICE)" fi echo # ── ③ 对齐工作区 ──────────────────────────────────────────── echo "③ 对齐工作区" cd "$REPO" || die "进不去 $REPO" rm -f .git/index.lock 2>/dev/null && ok "清掉了一个卡住的锁" git fetch -q origin main 2>/dev/null || warn "取线上失败(网络?)——先跳过" DIRTY=$(git status --porcelain 2>/dev/null | awk '{print $NF}') if [ -z "$DIRTY" ]; then ok "工作区本来就干净" else for f in $DIRTY; do if git diff --quiet FETCH_HEAD -- "$f" 2>/dev/null; then git checkout -- "$f" 2>/dev/null && ok "$f 内容线上已有,安全丢弃本地副本" else warn "$f 和线上不一样——保留不动,回头自己看一眼" fi done fi git pull -q --ff-only origin main 2>/dev/null ok "现在停在 $(git log -1 --format='%h %s' | cut -c1-60)" echo # ── ④ 装守护 ──────────────────────────────────────────────── echo "④ 装自动推守护" chmod +x "$BRIDGE/zy-push.sh" 2>/dev/null mkdir -p "$HOME/Library/LaunchAgents" "$HOME/Library/Logs" cat > "$PLIST" < Label${LABEL} ProgramArguments /bin/bash ${BRIDGE}/zy-push.sh StartInterval120 RunAtLoad StandardOutPath${LOGF} StandardErrorPath${LOGF} PLISTEOF launchctl bootout "gui/$(id -u)/${LABEL}" >/dev/null 2>&1 launchctl bootstrap "gui/$(id -u)" "$PLIST" >/dev/null 2>&1 || launchctl load "$PLIST" >/dev/null 2>&1 sleep 1 if launchctl print "gui/$(id -u)/${LABEL}" >/dev/null 2>&1; then ok "${LABEL} 已启动,每 120 秒扫一次" else warn "守护没能确认启动——但脚本能手动跑,见下面" fi echo # ── ④b 装手脚层守护 ───────────────────────────────────────── echo "④b 装手脚层(铸渊的手脚)" command -v python3 >/dev/null 2>&1 || warn "没找到 python3,手脚层装不了(自动推不受影响)" if command -v python3 >/dev/null 2>&1; then chmod +x "$BRIDGE/zy-limb.py" 2>/dev/null mkdir -p "/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/limb-queue/inbox" \ "/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/limb-queue/outbox" \ "/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/limb-queue/archive" \ "/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/limb-queue/for-codex" 2>/dev/null cat > "$PLIST2" < Label${LABEL2} ProgramArguments /usr/bin/python3 ${BRIDGE}/zy-limb.py StartInterval30 RunAtLoad StandardOutPath${LOGF2} StandardErrorPath${LOGF2} PL2EOF launchctl bootout "gui/$(id -u)/${LABEL2}" >/dev/null 2>&1 launchctl bootstrap "gui/$(id -u)" "$PLIST2" >/dev/null 2>&1 || launchctl load "$PLIST2" >/dev/null 2>&1 sleep 1 if launchctl print "gui/$(id -u)/${LABEL2}" >/dev/null 2>&1; then ok "${LABEL2} 已启动,每 30 秒收一次信" else warn "手脚层守护没能确认启动——可手动跑 python3 $BRIDGE/zy-limb.py" fi ok "任务信箱:BRIDGE/limb-queue/(inbox 收 · outbox 回执 · for-codex 转卡)" fi echo # ── 收尾:当场跑一次验收 ───────────────────────────────────── echo "⑤ 当场试一次" bash "$BRIDGE/zy-push.sh" if [ -f "$LOGF" ]; then echo " 日志末尾:" tail -3 "$LOGF" | sed 's/^/ /' else ok "没有待推的东西,所以没写日志(这是正常的)" fi echo echo "════════════════════════════════════════════" echo " 装好了。" echo echo " 以后铸渊往移动硬盘的工作区写东西,两分钟内自动提交并推到线上," echo " 不用再给令牌,也不用再管。" echo echo " 想看推送: tail -f $LOGF" echo " 想看手脚: tail -f $LOGF2" echo " 想立刻推一次: bash $BRIDGE/zy-push.sh" echo " 想停掉: launchctl bootout gui/\$(id -u)/${LABEL}" echo " launchctl bootout gui/\$(id -u)/${LABEL2}" echo "════════════════════════════════════════════" echo read -n1 -r -p "按任意键关闭这个窗口…"