Files
ISEP/scripts/github-arm.sh
T
Leo c2638668e3 ISEP 0.1.0:環境設定收成一個 plugin,本機與雲端共用一份
leo 2026-08-20:「同一個 plugin 你用,薄殼也用,保證兩邊同步」
              「我要你幫雲端做薄殼,永遠都有問題,你要做的就是這組設定
                你自己可以 dogfooding」

搬進來:41 支 hook(51 條註冊)/7 支 command/2 支 skill/23 支腳本。
不搬 .env、wiki、docs——那些是知識不是環境。

51 條 hook 路徑全部從 $CLAUDE_PROJECT_DIR/.claude/hooks/ 改成 ${CLAUDE_PLUGIN_ROOT}/hooks/,
零漏網。那正是薄殼一直壞掉的根:雲端 cwd 不是真身,寫死路徑就斷。

尚未驗證:Claude Code 能不能從私有 Gitea repo 裝 marketplace(要憑證)。
下一步就是在本機實際裝一次,通了才動雲端 bootstrap.sh。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:41:46 +08:00

97 lines
5.0 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# github-arm.sh — 解除 GitHub 接觸保險(D20 發射鈕,leo 親手跑,AI 不得代跑)
# 用法:scripts/github-arm.sh "任務描述" [有效分鐘,預設30,上限60]
set -euo pipefail
if [ ! -t 0 ]; then
echo "❌ 本腳本必須由人類在終端機互動執行(防 AI 代按發射鈕)。" >&2
exit 1
fi
MISSION="${1:-}"
MINUTES="${2:-30}"
if [ -z "$MISSION" ]; then
echo "用法:scripts/github-arm.sh \"任務描述\" [分鐘]" >&2
exit 1
fi
# 第二參數必須是純數字分鐘。2026-08-01 leo 實撞:AI 給的指令把中文註解寫在同一行,
# 被當成分鐘數 → 下方 $(( )) 算術炸掉 → EXPIRY unbound、保險沒解成卻看似執行過。
case "$MINUTES" in
''|*[!0-9]*)
echo "❌ 第二個參數要純數字分鐘(收到:$MINUTES" >&2
echo " 正確:scripts/github-arm.sh \"任務描述\" 30" >&2
exit 1;;
esac
if [ "$MINUTES" -gt 60 ]; then MINUTES=60; fi
if [ "$MINUTES" -lt 1 ]; then MINUTES=1; fi
cd "$(dirname "$0")/.."
# ── 搬遷預覽(arcrun-rag#27,leo:「解保險前要看得到這次會搬什麼」)──────────
# 純讀本機已存在的檔案(ship.targets.json + stage/prod 兩份 manifest.json),
# 完全不碰網路——此刻保險還沒解,不能在這裡先觸網。
# 找不到這些檔就安靜略過(本腳本不是只給出貨用,其他 GitHub 任務沒有這些檔是正常的)。
ARCRUN_RAG_TARGETS="products/arcrun-rag/installer/ship.targets.json"
STAGE_BUNDLE_DIR="/private/tmp/arcrun-rag-bundles-staging"
PROD_BUNDLE_DIR="/private/tmp/arcrun-rag-bundles"
if [ -f "$ARCRUN_RAG_TARGETS" ] && [ -f "$STAGE_BUNDLE_DIR/manifest.json" ] && [ -f "$PROD_BUNDLE_DIR/manifest.json" ]; then
echo "═══════════════════════════════════════════"
echo "📦 搬遷預覽(只讀本機檔案,尚未碰網路)"
echo "═══════════════════════════════════════════"
python3 - "$ARCRUN_RAG_TARGETS" "$STAGE_BUNDLE_DIR" "$PROD_BUNDLE_DIR" <<'PYEOF' || echo "(搬遷預覽讀檔失敗,略過——不影響下面的保險流程)"
import json, os, sys
targets_json, stage_dir, prod_dir = sys.argv[1], sys.argv[2], sys.argv[3]
cfg = json.load(open(targets_json))
prod = cfg.get("targets", {}).get("prod", {})
remote = prod.get("bundles", {}).get("remote", "(未知)")
branch = prod.get("bundles", {}).get("branch", "main")
stage = json.load(open(os.path.join(stage_dir, "manifest.json")))
prodm = json.load(open(os.path.join(prod_dir, "manifest.json")))
print(f"搬到哪:{remote}branch {branch}")
print(f"版本:prod 目前 {prodm.get('release')} → stage 現在是 {stage.get('release')}")
stage_core = {c.get("name"): c.get("sha256", "") for c in stage.get("core", [])}
prod_core = {c.get("name"): c.get("sha256", "") for c in prodm.get("core", [])}
changed = [n for n in prod_core if stage_core.get(n) != prod_core.get(n)]
same = [n for n in prod_core if n in stage_core and stage_core.get(n) == prod_core.get(n)]
print(f"prod 管的 {len(prod_core)} 顆裡,內容會變的:{len(changed)} 顆")
for n in changed:
print(f" - {n}")
if same:
print(f"內容沒變(sha 相同):{len(same)} 顆 — {', '.join(same)}")
has_local_clone = os.path.isdir(os.path.join(prod_dir, ".git"))
est = "1 次(push;沿用已存在的本地 clone,不需再 clone" if has_local_clone \
else "2 次(clone 1 + push 1;本地還沒有這個 clone"
print(f"預估碰 GitHub 幾次:{est}")
print("(不含 jsDelivr purge——那是 CDN 快取清除,不算 GitHub 接觸,ROE 不計)")
PYEOF
echo ""
else
echo "(找不到本地 stage/prod bundle 的 manifest.json,略過搬遷預覽——非出貨類任務屬正常)"
echo ""
fi
echo "═══════════════════════════════════════════"
echo "🚀 GitHub 接觸儀式 — 發射前檢查(ROE)"
echo "═══════════════════════════════════════════"
echo "任務:$MISSION"
echo "時效:$MINUTES 分鐘(到期自動回保險)"
echo ""
echo "交戰規則(每條都要守):"
echo " □ 單一 repo,不跨 repo fan-out"
echo " □ 網路請求 ≤5 次(clone/push/PR 各算一次)"
echo " □ 禁批量操作、禁迴圈打 API、禁開/改 Actions"
echo " □ 動作間隔像人手(秒級間隔,不連發)"
echo " □ 一收到 403/429/驗證挑戰 → 立即全停回報"
echo ""
read -r -p "以上確認,解除保險?(yes/N) " CONFIRM
if [ "$CONFIRM" != "yes" ]; then
echo "已取消,保險維持。"
exit 0
fi
EXPIRY=$(( $(date +%s) + MINUTES * 60 ))
printf '%s\n%s\n%s\n' "$EXPIRY" "$MISSION" "armed_at=$(date '+%Y-%m-%d %H:%M:%S')" > .github-armed
echo ""
echo "✅ 保險已解除至 $(date -r "$EXPIRY" '+%H:%M:%S')。期間每次 GitHub 接觸自動記入 github-contact-log.md。"
echo " 提前上保險:rm .github-armed"