From 3ca066260c2dc93b5bfc7ddd14b481b9575a438c Mon Sep 17 00:00:00 2001 From: richblack Date: Thu, 20 Aug 2026 22:09:36 +0800 Subject: [PATCH] =?UTF-8?q?fix(cloud):=20make-cloud-env.sh=20=E6=94=B9?= =?UTF-8?q?=E4=B8=89=E6=AE=B5=E8=BC=B8=E5=87=BA=EF=BC=88A/B/C=EF=BC=89?= =?UTF-8?q?=EF=BC=8B=E4=BF=AE=20bash=203.2=20=E7=9B=B8=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit main 回饋:靜默排除 leo21c 憑證會讓 leo 明天卡住而不知道為什麼—— 改成 A(cloud 總管工作需要,直接貼)/B(leo21c 正式環境憑證+已知過時, 值已備好+附理由,leo 自己決定要不要留)/C(舊雲端有這個名字但本機 六個 .env 都找不到值的)三段,讓 leo 自己看得見取捨。 同時修掉 `local -n`(nameref)在 macOS 內建 bash 3.2 會直接噴語法錯誤的問題 (leo 本機跑的就是這支 bash)——改成兩個各自展開的函式,不依賴 bash 4.3+。 實跑驗證:A 8 個+B 7 個=15 個,跟舊雲端環境變數清單數量一致,C 段 0 個 (這次盤點六個 .env 全部找得到值)。 Co-Authored-By: Claude Opus 5 --- scripts/make-cloud-env.sh | 128 ++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 40 deletions(-) diff --git a/scripts/make-cloud-env.sh b/scripts/make-cloud-env.sh index 56b7a8f..b3e494d 100755 --- a/scripts/make-cloud-env.sh +++ b/scripts/make-cloud-env.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# 管什麼: 產生「可以直接貼進 claude.ai Cloud environment」的兩塊內容,值由本腳本自己去 .env 拉。 +# 管什麼: 產生「可以直接貼進 claude.ai Cloud environment」的內容,值由本腳本自己去 .env 拉。 # 為什麼: leo 2026-08-20「這些值你都有,你可以只寫名字然後 build 一個檔案給我」—— # 之前的做法是叫他自己拼湊,或叫他把設定貼給 AI 看,兩種都錯(一個沒效率,一個讓值經過對話)。 # 誤觸時怎麼關: 這支不擋任何東西。不想產生就別跑;產物在版控外,刪掉即可。 @@ -7,33 +7,14 @@ # 用法:bash scripts/make-cloud-env.sh # 產物:~/.claude/cloud-env/<日期>.txt(權限 600,**不在任何 repo 裡**) # 本腳本只寫「變數名字」,值在執行當下才從既有 .env 讀出來寫進產物 —— 值不進版控、不進對話。 +# +# 🔴 2026-08-20(inkstone/InkStoneCo#14)分三段輸出,不是「總管幫你篩過」: +# 舊雲端環境的 15 個變數,逐一對過 credentials-map.md 後發現有 7 個其實是 +# polaris/mira/.env(leo21c 現役)的正式環境憑證。總管第一版做法是「照抄 +# 舊清單、值填回去」——沒有問過「這些憑證憑什麼該出現在雲端」,那是錯的。 +# 但「總管建議不放」≠「總管替你拿掉」:B 段照樣給值+理由,你自己決定。 set -euo pipefail -# ── 雲端需要哪些變數(只有名字。要加就加在這裡)────────────────── -# 2026-08-20 盤點(inkstone/InkStoneCo#14):舊雲端環境幾乎整包搬自 -# polaris/mira/.env(🔴 leo21c 現役),混進了 leo21c 的 CF 帳號憑證與 -# Google 服務帳號私鑰。下面這份清單是逐一對過 credentials-map.md 之後 -# 篩出的「cloud 總管實際會用到、且不是 leo21c 寫入憑證」的變數。 -# 刻意不收:CLOUDFLARE_ACCOUNT_ID/CLOUDFLARE_API_TOKEN(無名字的)/ -# PRIVATE_KEY/CLIENT_EMAIL/NAMESPACE——這些是 mira 自己的憑證,不是 -# cloud CC session 的需求,留著只會平白多一份 leo21c 暴露面。 -# 完整分析見 docs/cloud-environment-audit-20260820.md §7。 -NEEDED=( - GITEA_TOKEN_CLAUDE_CODE # 機器帳號 claude-code 的 Gitea token;plugin 安裝與 git push-back 都靠它 - TELEGRAM_BOT_TOKEN # notify_leo 備援路徑(優先路徑是 arcrun MCP workflow,免密碼) - TELEGRAM_CHAT_ID # 同上 - GEMINI_API_KEY # arcrun 工作流用(matrix/arcrun、products/arcrun-rag 兩邊 .env 都列) - NOTION_INTEGRATION_TOKEN # leo 註記「給 arcrun 用的」 - UNCLE6_CF_API_KEY # uncle6 帳號(非 leo21c)的 CF 操作 - N8N_UNCLE6_API_KEY # n8n MCP 用 - CLOUDFLARE_API_TOKEN_YOULIN_CC_USE # D37 測試帳號,本來就是設計給 CC 用的 -) -# 下面兩個不放進 NEEDED(會讓 leo 自己決定要不要開,見審計文件 §7 尾段): -# CLOUDFLARE_API_TOKEN_CC_SHIPPING_CORE / CLOUDFLARE_ACCOUNT_ID_GEEK6688 -# ——加了雲端就有 geek6688 出貨機的寫入能力,是否要開屬於 leo 的風險判斷。 -# 要加:手動在 NEEDED 陣列補上這兩個名字即可,值一樣是這支腳本自動去 .env 撈。 - -# ── 去哪裡找值(credentials-map.md 記的六個 .env)──────────────── BASE="${INKSTONE_ROOT:-$HOME/Documents/tech_projects/InkStoneCo}" ENV_FILES=( "$BASE/.env" @@ -44,7 +25,7 @@ ENV_FILES=( "$BASE/arcrun_harness/.env" ) -lookup() { # $1=變數名 → 印出值(找不到就空) +lookup() { # $1=變數名 → 印出值(找不到就空、回傳非 0) local name="$1" f v for f in "${ENV_FILES[@]}"; do [ -f "$f" ] || continue @@ -56,6 +37,37 @@ lookup() { # $1=變數名 → 印出值(找不到就空) return 1 } +# ── A. cloud 總管工作需要的(只有名字+一句理由。要加就加在這裡)────── +A_NEEDED=( + "GITEA_TOKEN_CLAUDE_CODE|機器帳號 claude-code 的 Gitea token;plugin 安裝與 git push-back 都靠它" + "TELEGRAM_BOT_TOKEN|notify_leo 備援路徑(優先路徑是 arcrun MCP workflow,免密碼)" + "TELEGRAM_CHAT_ID|同上" + "GEMINI_API_KEY|arcrun 工作流用(matrix/arcrun、products/arcrun-rag 兩邊 .env 都列)" + "NOTION_INTEGRATION_TOKEN|leo 註記「給 arcrun 用的」" + "UNCLE6_CF_API_KEY|uncle6 帳號(非 leo21c)的 CF 操作" + "N8N_UNCLE6_API_KEY|n8n MCP 用" + "CLOUDFLARE_API_TOKEN_YOULIN_CC_USE|D37 測試帳號,本來就是設計給 CC 用的" +) +# 想加 geek6688 出貨機能力(讓雲端能自走完 D82 三步)就在這裡補兩行: +# "CLOUDFLARE_API_TOKEN_CC_SHIPPING_CORE|geek6688 出貨機 token——加了雲端就有出貨寫入能力" +# "CLOUDFLARE_ACCOUNT_ID_GEEK6688|同上,成對變數" +# 沒有預設放進來,因為那是「要不要讓雲端有出貨能力」的風險判斷,屬於 leo。 + +# ── B. 建議不放,但值已備好+附理由,leo 自己決定要不要留 ──────────── +# 前 5 項全部來自 polaris/mira/.env(leo21c 現役正式環境),不是 cloud 總管 +# 工作需要的東西;credentials-map.md 逐檔核對,2026-08-14 那輪審查已把 +# 「無名字的 CLOUDFLARE_API_TOKEN 讀得到 leo21c 6 顆正式 worker」列為 +# 「本輪最危險的發現」。完整依據見 docs/cloud-environment-audit-20260820.md §7。 +B_LEGACY=( + "NAMESPACE|mira(leo21c 現役)自己的環境變數,cloud 總管的工作不吃它;拿掉沒有已知副作用" + "PRIVATE_KEY|mira 用的 Google 服務帳號私鑰;拿掉沒有已知副作用(cloud 總管目前的工作不碰 Google API)" + "CLIENT_EMAIL|PRIVATE_KEY 的配對變數,同上" + "CLOUDFLARE_API_TOKEN|沒有名字,實測讀得到 leo21c 的 6 顆正式 worker,會被所有工具當預設 token;拿掉會失去「不指定帳號也能操作 CF」的能力——但那正是最危險的情境本身,不是值得保留的功能" + "CLOUDFLARE_ACCOUNT_ID|= leo21c 帳號 id;拿掉會讓 CLI 不再預設打 leo21c——這是拿掉的目的,不是副作用" + "CLAUDE_CODE_OAUTH_TOKEN|leo 自己在舊快照裡標記「這個已經不需要了」;拿掉沒有已知副作用" + "CLOUDFLARE_API_TOKEN_leo21c|明確具名指向 leo21c;留著的話能對 leo21c 做診斷(GET),但風險是否可接受要看這把 token 在 CF 控制台的實際權限範圍——這台機器沒辦法幫你查,请自己到 CF dashboard 確認是唯讀還是可寫" +) + OUT_DIR="$HOME/.claude/cloud-env" mkdir -p "$OUT_DIR"; chmod 700 "$OUT_DIR" OUT="$OUT_DIR/$(date +%Y%m%d-%H%M%S).txt" @@ -63,26 +75,62 @@ OUT="$OUT_DIR/$(date +%Y%m%d-%H%M%S).txt" SETUP="$(cd "$(dirname "$0")/.." && pwd)/docs/cloud-setup-script.sh" [ -f "$SETUP" ] || { echo "🔴 找不到 $SETUP" >&2; exit 1; } -MISSING=() -{ - echo "claude.ai → Cloud environments → 你的環境。下面兩塊各自貼進對應欄位。" - echo "產生時間:$(date '+%Y-%m-%d %H:%M')" - echo - echo "════════ ① Environment variables(一行一個,名字與值分開填)════════" - for n in "${NEEDED[@]}"; do - if v=$(lookup "$n"); then - echo "$n=$v" +MISSING_NAMES=() # A/B 兩段裡,本機 .env 完全找不到值的(落進 C 段) + +# bash 3.2(macOS 內建)沒有 `local -n`(nameref),這裡故意不用函式傳陣列名, +# 兩段各自展開迴圈,維持跨平台可跑(leo 本機/雲端 Ubuntu 都要能跑)。 +render_A() { + local entry name reason v + for entry in "${A_NEEDED[@]}"; do + name="${entry%%|*}"; reason="${entry#*|}" + if v=$(lookup "$name"); then + printf '%s=%s ← %s\n' "$name" "$v" "$reason" else - echo "$n=<🔴 這台機器的 .env 裡找不到,要 leo 提供>" - MISSING+=("$n") + MISSING_NAMES+=("$name") fi done +} +render_B() { + local entry name reason v + for entry in "${B_LEGACY[@]}"; do + name="${entry%%|*}"; reason="${entry#*|}" + if v=$(lookup "$name"); then + printf '%s=%s ← %s\n' "$name" "$v" "$reason" + else + MISSING_NAMES+=("$name") + fi + done +} + +{ + echo "claude.ai → Cloud environments → 你的環境。" + echo "產生時間:$(date '+%Y-%m-%d %H:%M')" + echo "依據:docs/cloud-environment-audit-20260820.md §7(完整比對表與理由)" echo - echo "════════ ② Setup script(整段貼,一字不改)════════" + echo "════════ A. Environment variables — cloud 總管工作需要,直接貼 ════════" + render_A + echo + echo "════════ B. leo21c 正式環境憑證/已知過時 — 建議不放,值已備好,你決定 ════════" + echo "# 格式:NAME=值 ← 為什麼建議不放" + echo "# 要留哪一條,把那一行搬到上面 A 段、拿掉後面的「← 理由」註解即可" + render_B + echo + echo "════════ C. 舊雲端有這個名字、但本機六個 .env 都找不到值 ════════" + if [ ${#MISSING_NAMES[@]} -eq 0 ]; then + echo "(無——A/B 兩段的變數這台機器上全部找得到值)" + else + for n in "${MISSING_NAMES[@]}"; do + echo "$n=<🔴 這台機器找不到,若還要這個能力,從舊的雲端設定手動搬過來>" + done + fi + echo + echo "════════ D. Setup script(整段貼,一字不改)════════" cat "$SETUP" } > "$OUT" chmod 600 "$OUT" +A_COUNT=${#A_NEEDED[@]} +B_COUNT=${#B_LEGACY[@]} echo "✅ 產生完成:$OUT" -echo " 變數 ${#NEEDED[@]} 個|找不到值的 ${#MISSING[@]} 個 ${MISSING[*]:-}" +echo " A 段 $A_COUNT 個(直接貼)|B 段 $B_COUNT 個(建議不放,附值與理由)|C 段找不到值 ${#MISSING_NAMES[@]} 個 ${MISSING_NAMES[*]:-}" echo " 🔴 這個檔含金鑰真身:貼完就刪(rm '$OUT'),它刻意不在任何 repo 裡。"