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>
This commit is contained in:
2026-08-20 11:41:46 +08:00
commit c2638668e3
85 changed files with 11879 additions and 0 deletions
+96
View File
@@ -0,0 +1,96 @@
#!/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"