From c0a6b6a46559763a9748cab013142b8ab0ad1ae5 Mon Sep 17 00:00:00 2001 From: richblack Date: Thu, 25 Jun 2026 20:47:46 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20update.sh=20=E4=B8=8D=E5=86=8D=E8=A6=86?= =?UTF-8?q?=E8=93=8B=E5=AE=A2=E8=A3=BD=20pre-write-guard.sh=EF=BC=88issue?= =?UTF-8?q?=20#3=EF=BC=89+=20bump=201.3.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update.sh 原把 pre-write-guard.sh 列在無條件覆蓋區,會用模板空殼 無聲蓋掉下游已客製的 guardrail,且 update_file 無 .bak 備份。 改法(issue 方案 1):新增 keep_with_template()——原檔永不覆蓋, 最新模板版另存 pre-write-guard.template.sh 旁邊,結尾印 diff 指令供採納。 首次安裝(原檔不存在)才走 update_file 抓本體。 Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 12 ++++++++++++ scripts/update.sh | 39 ++++++++++++++++++++++++++++++++++++++- template/.claude/VERSION | 2 +- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb5c363..ca8ecf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,18 @@ --- +## 1.3.1 — 修:update.sh 不再覆蓋客製的 pre-write-guard.sh(issue #3) + +**修正** +- `scripts/update.sh` 原本把 `pre-write-guard.sh` 列在「覆蓋更新」區,**無條件**用模板空殼蓋掉。 + 但此檔的定位是「使用者手填的 guardrail 客製檔」(CHANGELOG 1.2.0),下游通常已塞滿自己的 enforcement, + 且 `update_file` 覆蓋**無 `.bak` 備份**——跑一次 update 等於無聲關掉整套 guardrail(如 Arcrun 的 KNOWN_SDDS 白名單、薄殼原則強制等數百行)。 +- 改法(issue 建議方案 1):新增 `keep_with_template()`,把 `pre-write-guard.sh` 移出覆蓋區。 + **原檔永不覆蓋**,改把最新模板版另存成 `pre-write-guard.template.sh` 旁邊,更新結尾印出 `diff` 指令供使用者自行採納。 + 首次安裝(原檔不存在)才會直接抓本體。`install.sh` 路徑本就用 `download_if_missing`(已存在即跳過),無此問題。 + +--- + ## 1.3.0 — vault 偵測(Logseq / Obsidian)+ Cowork 整理 skill **新增** diff --git a/scripts/update.sh b/scripts/update.sh index 6ccd0c5..c8eb60d 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -21,6 +21,7 @@ TEMPLATE_URL="$REPO_RAW/template" UPDATED=() KEPT=() NEW=() +TEMPLATED=() # ── 版本比對:先看本機 vs 遠端,給使用者「值不值得更新」的判斷 ── LOCAL_VER="(未知)" @@ -77,6 +78,29 @@ keep_file() { [ -f "$1" ] && KEPT+=("$1") || true } +# 客製檔:使用者一定會手填內容(如 pre-write-guard.sh)。 +# - 已存在 → 絕不覆蓋,但把最新模板版抓到 <檔名>.template.sh 旁邊,供使用者自行 diff 採納。 +# - 不存在 → 視同新檔,直接抓本體(第一次安裝才會走這條)。 +keep_with_template() { + local dest="$1" src="$2" + if [ -f "$dest" ]; then + KEPT+=("$dest") + local tmpl="${dest%.sh}.template.sh" + if curl -sSL "$src" -o "$tmpl.tmp" 2>/dev/null && [ -s "$tmpl.tmp" ]; then + if [ -f "$tmpl" ] && cmp -s "$tmpl" "$tmpl.tmp"; then + rm -f "$tmpl.tmp" # 模板版沒變,不重複提示 + else + mv "$tmpl.tmp" "$tmpl" + TEMPLATED+=("$tmpl") + fi + else + rm -f "$tmpl.tmp" + fi + else + update_file "$dest" "$src" # 還沒裝過 → 當新檔處理 + fi +} + # ── 偵測已安裝哪些模組(依現有檔案判斷,更新只動已裝的)── HAS_WIKI=false HAS_SDD=false @@ -89,9 +113,14 @@ $HAS_SDD && echo " • SDD" { $HAS_WIKI || $HAS_SDD; } || echo " (未偵測到任何模組——這裡可能還沒安裝,請改跑 install.sh)" echo "" +# ── 客製檔:使用者手填的 guardrail,永不覆蓋(issue #3)── +# pre-write-guard.sh 的定位是「空白客製模板,使用者沒配置前不提供保護」(CHANGELOG 1.2.0)。 +# 下游通常已塞滿自己的 enforcement,直接覆蓋=無聲關掉整套 guardrail。 +# 改為:保留原檔不動,新版範本另存 pre-write-guard.template.sh,由使用者自行 diff 採納。 +keep_with_template ".claude/hooks/pre-write-guard.sh" "$TEMPLATE_URL/.claude/hooks/pre-write-guard.sh" + # ── 模板/邏輯檔:覆蓋更新 ────────────────────────── # 共用 hook 與指引 -update_file ".claude/hooks/pre-write-guard.sh" "$TEMPLATE_URL/.claude/hooks/pre-write-guard.sh" update_file ".claude/commands/issue-handle.md" "$TEMPLATE_URL/.claude/commands/issue-handle.md" update_file ".claude/VERSION" "$TEMPLATE_URL/.claude/VERSION" @@ -154,6 +183,14 @@ if [ ${#KEPT[@]} -gt 0 ]; then echo "🔒 完整保留(你的內容/設定,從未碰過):" for f in "${KEPT[@]}"; do echo " = $f"; done fi +if [ ${#TEMPLATED[@]} -gt 0 ]; then + echo "" + echo "📋 客製檔有新版範本(你的原檔沒動,新版另存旁邊,請自行 diff 採納):" + for f in "${TEMPLATED[@]}"; do + echo " → $f" + echo " 比對:diff \"${f%.template.sh}.sh\" \"$f\"" + done +fi # ── settings.json 提醒:新模組 hook 可能要手動補 ── if [ -f ".claude/settings.json" ]; then diff --git a/template/.claude/VERSION b/template/.claude/VERSION index f0bb29e..3a3cd8c 100644 --- a/template/.claude/VERSION +++ b/template/.claude/VERSION @@ -1 +1 @@ -1.3.0 +1.3.1