feat: 舊版一鍵更新 update.sh + VERSION + CHANGELOG
舊版使用者升級的雞生蛋問題:本機沒有 update.sh,第一次靠 README 的 curl 從遠端抓更新器來跑,跑完它把自己裝進 scripts/update.sh, 之後直接跑本機的即可。 update.sh 只覆蓋模板/邏輯檔(hooks、commands、TEMPLATE-*),完全 不碰使用者資料(wiki 內容、.wikiignore、settings.json、CLAUDE.md)。 依已裝模組自動偵測該更新什麼,並比對 VERSION 列出新功能。 新增 template/.claude/VERSION 作為版本基準、CHANGELOG.md 記錄每版 變動,README 加更新區段與 CHANGELOG 連結。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
# 更新紀錄 CHANGELOG
|
||||||
|
|
||||||
|
> 每次改了什麼,都記在這。版號對應 `template/.claude/VERSION`。
|
||||||
|
> 想更新到最新版?看 [README → 一鍵更新](README.md#-已安裝舊版一鍵更新)。
|
||||||
|
|
||||||
|
版號規則(語意化版本,簡化版):
|
||||||
|
- **大版號**(1.x → 2.x):破壞性變動,舊專案更新後可能要手動調整。
|
||||||
|
- **中版號**(1.0 → 1.1):加了新功能,向下相容,更新即用。
|
||||||
|
- **小版號**(1.1.0 → 1.1.1):修 bug、改文件,無新功能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1.1.0 — 一鍵更新
|
||||||
|
|
||||||
|
**新增**
|
||||||
|
- `scripts/update.sh`:已安裝舊版的人,一行指令更新到最新版。
|
||||||
|
只覆蓋模板/邏輯檔(hooks、commands、TEMPLATE-*),**完全不碰**使用者資料
|
||||||
|
(`wiki/status.md`、`mistakes.md`、`decisions-summary.md`、`.wikiignore`、`settings.json`、`CLAUDE.md`)。
|
||||||
|
會先比對版本、列出新功能、依已裝模組自動偵測該更新什麼,跑完自我更新。
|
||||||
|
- `template/.claude/VERSION`:版本基準檔,讓「檢查新版」有依據。
|
||||||
|
- `CHANGELOG.md`(本檔)。
|
||||||
|
|
||||||
|
**第一次更新的雞生蛋問題**:舊版本機還沒有 `update.sh`,所以第一次靠 README 那行
|
||||||
|
`curl` 從遠端抓更新器來跑;跑完它把自己裝進 `scripts/update.sh`,之後直接跑本機的即可。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1.0.0 — 模組化安裝(基準版)
|
||||||
|
|
||||||
|
此版本之前無 VERSION 檔,以下為依 git 歷史回溯的功能基準。
|
||||||
|
|
||||||
|
- `scripts/install.sh` 模組化安裝:`--wiki` / `--sdd` / `--all`,無參數則互動詢問。
|
||||||
|
- **LLM Wiki**:CC 記憶系統(INDEX / status / mistakes / decisions-summary)
|
||||||
|
+ 接關 hook(session-start-recall)+ 對應 slash commands。
|
||||||
|
- **wiki 機敏防護三層**:`.wikiignore`(檔案層)+行內標記(局部)+
|
||||||
|
`wiki-secret-scan.sh`(機械兜底攔截)。
|
||||||
|
- **SDD 強制**:動 code 前必須有 `design.md`,由 `sdd-guard.sh` hook 把關,附 TEMPLATE 範本。
|
||||||
|
- docs 分類結構(1-vision ~ 6-user)與 ADR 範本。
|
||||||
@@ -65,6 +65,33 @@ CC 會掃描現有文件、建立 wiki、整理 docs 結構。
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🔄 已安裝舊版?一鍵更新
|
||||||
|
|
||||||
|
聽到出新功能了,想升級到最新版,跑這一行就好:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd your-project
|
||||||
|
curl -sSL https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main/scripts/update.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
它會先比對你的版本和最新版,告訴你**多了哪些新功能**,然後:
|
||||||
|
|
||||||
|
| 動作 | 對象 |
|
||||||
|
|------|------|
|
||||||
|
| 🆕 **補上**新功能(舊版沒有的 hook / command / 範本) | 模板檔 |
|
||||||
|
| ⬆️ **更新**模板邏輯(hooks、commands、TEMPLATE-* 換成新版) | 模板檔 |
|
||||||
|
| 🔒 **完全不碰**你的內容與設定 | `wiki/status.md`、`mistakes.md`、`decisions-summary.md`、`.wikiignore`、`settings.json`、`CLAUDE.md` |
|
||||||
|
|
||||||
|
> **為什麼第一次要用 curl?** 舊版本機還沒有 `update.sh`,所以第一次得從遠端抓它下來跑。
|
||||||
|
> 跑完它會把自己也裝進 `scripts/update.sh`,**之後更新直接跑** `bash scripts/update.sh` 就好,不用再 curl。
|
||||||
|
|
||||||
|
更新只會動「已安裝的模組」(裝了 wiki 就更新 wiki,裝了 SDD 就更新 SDD),偵測自動完成。
|
||||||
|
若 `settings.json` 缺了新版才有的 hook,它不會幫你改設定,但會在結尾**列出來提醒你手動補**(不擅自動你的設定)。
|
||||||
|
|
||||||
|
📜 想知道每次改了什麼、現在是哪一版?看 **[更新紀錄 CHANGELOG](CHANGELOG.md)**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 目錄說明
|
## 目錄說明
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -82,7 +109,8 @@ system-dev-template/
|
|||||||
│ └── llm-wiki/ ← 複製到 Legacy-Workspace/.claude/skills/
|
│ └── llm-wiki/ ← 複製到 Legacy-Workspace/.claude/skills/
|
||||||
│
|
│
|
||||||
├── scripts/
|
├── scripts/
|
||||||
│ └── install.sh ← 已有專案接入腳本
|
│ ├── install.sh ← 已有專案接入腳本
|
||||||
|
│ └── update.sh ← 舊版一鍵更新(只換模板,不碰你的資料)
|
||||||
│
|
│
|
||||||
└── docs/ ← 這個 repo 自己的說明
|
└── docs/ ← 這個 repo 自己的說明
|
||||||
├── why.md ← 設計理念
|
├── why.md ← 設計理念
|
||||||
|
|||||||
Executable
+174
@@ -0,0 +1,174 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# system-dev-template updater
|
||||||
|
# 已安裝舊版的人,一鍵更新到新版。
|
||||||
|
#
|
||||||
|
# 核心安全原則:只覆蓋「模板/邏輯檔」,絕不碰「使用者資料檔」。
|
||||||
|
# ✅ 可覆蓋:hooks/*.sh、commands/*.md、TEMPLATE-*、wiki/INDEX.md
|
||||||
|
# ——這些由模板維護,使用者不會手改,新版直接換掉。
|
||||||
|
# 🔒 絕不碰:wiki/status.md、mistakes.md、decisions-summary.md、.wikiignore、
|
||||||
|
# settings.json、CLAUDE.md
|
||||||
|
# ——這些是使用者自己填的內容,覆蓋=清空他的記憶與設定。
|
||||||
|
#
|
||||||
|
# 「第一次更新」的雞生蛋問題:
|
||||||
|
# 舊版本機沒有 update.sh。所以第一次靠 README 那行 curl 從遠端抓這支腳本來跑。
|
||||||
|
# 跑完它會把自己也更新進 scripts/update.sh,之後就能直接跑本機的 `bash scripts/update.sh`。
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_RAW="https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main"
|
||||||
|
TEMPLATE_URL="$REPO_RAW/template"
|
||||||
|
|
||||||
|
UPDATED=()
|
||||||
|
KEPT=()
|
||||||
|
NEW=()
|
||||||
|
|
||||||
|
# ── 版本比對:先看本機 vs 遠端,給使用者「值不值得更新」的判斷 ──
|
||||||
|
LOCAL_VER="(未知)"
|
||||||
|
[ -f ".claude/VERSION" ] && LOCAL_VER="$(tr -d '[:space:]' < .claude/VERSION)"
|
||||||
|
REMOTE_VER="$(curl -sSL "$TEMPLATE_URL/.claude/VERSION" 2>/dev/null | tr -d '[:space:]' || echo '')"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔄 system-dev-template updater"
|
||||||
|
echo "================================="
|
||||||
|
echo " 本機版本:${LOCAL_VER:-未知}"
|
||||||
|
echo " 最新版本:${REMOTE_VER:-取不到(檢查網路)}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ -z "$REMOTE_VER" ]; then
|
||||||
|
echo "❌ 取不到遠端版本,可能是網路問題。請稍後再試。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$LOCAL_VER" = "$REMOTE_VER" ]; then
|
||||||
|
echo "✅ 已是最新版($LOCAL_VER),不需更新。"
|
||||||
|
echo " (仍會同步模板邏輯檔,確保 hooks/commands 與最新一致。)"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 工具函式 ───────────────────────────────────────
|
||||||
|
# 覆蓋更新:模板/邏輯檔,無條件抓最新版蓋掉。
|
||||||
|
update_file() {
|
||||||
|
local dest="$1" src="$2"
|
||||||
|
mkdir -p "$(dirname "$dest")"
|
||||||
|
if [ -f "$dest" ]; then
|
||||||
|
if curl -sSL "$src" -o "$dest.tmp" 2>/dev/null && [ -s "$dest.tmp" ]; then
|
||||||
|
if cmp -s "$dest" "$dest.tmp"; then
|
||||||
|
rm -f "$dest.tmp" # 內容相同,不算更新
|
||||||
|
else
|
||||||
|
mv "$dest.tmp" "$dest"
|
||||||
|
UPDATED+=("$dest")
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
rm -f "$dest.tmp"
|
||||||
|
echo " ⚠️ 抓取失敗,保留原檔:$dest"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if curl -sSL "$src" -o "$dest" 2>/dev/null && [ -s "$dest" ]; then
|
||||||
|
NEW+=("$dest") # 新功能:舊版沒有的檔
|
||||||
|
else
|
||||||
|
rm -f "$dest"
|
||||||
|
echo " ⚠️ 抓取失敗:$dest"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 保留:使用者資料檔,只記錄「有保留」,永遠不動。
|
||||||
|
keep_file() {
|
||||||
|
[ -f "$1" ] && KEPT+=("$1") || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 偵測已安裝哪些模組(依現有檔案判斷,更新只動已裝的)──
|
||||||
|
HAS_WIKI=false
|
||||||
|
HAS_SDD=false
|
||||||
|
[ -d ".claude/wiki" ] && HAS_WIKI=true
|
||||||
|
if [ -f ".claude/hooks/sdd-guard.sh" ] || [ -d "docs/3-specs/TEMPLATE-sdd" ]; then HAS_SDD=true; fi
|
||||||
|
|
||||||
|
echo "📦 偵測到已安裝模組:"
|
||||||
|
$HAS_WIKI && echo " • LLM Wiki"
|
||||||
|
$HAS_SDD && echo " • SDD"
|
||||||
|
{ $HAS_WIKI || $HAS_SDD; } || echo " (未偵測到任何模組——這裡可能還沒安裝,請改跑 install.sh)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# ── 模板/邏輯檔:覆蓋更新 ──────────────────────────
|
||||||
|
# 共用 hook
|
||||||
|
update_file ".claude/hooks/pre-write-guard.sh" "$TEMPLATE_URL/.claude/hooks/pre-write-guard.sh"
|
||||||
|
update_file ".claude/VERSION" "$TEMPLATE_URL/.claude/VERSION"
|
||||||
|
|
||||||
|
if $HAS_WIKI; then
|
||||||
|
# wiki 的「邏輯檔」:導航與 hooks,可覆蓋
|
||||||
|
update_file ".claude/wiki/INDEX.md" "$TEMPLATE_URL/.claude/wiki/INDEX.md"
|
||||||
|
update_file ".claude/hooks/session-start-recall.sh" "$TEMPLATE_URL/.claude/hooks/session-start-recall.sh"
|
||||||
|
update_file ".claude/hooks/wiki-secret-scan.sh" "$TEMPLATE_URL/.claude/hooks/wiki-secret-scan.sh"
|
||||||
|
update_file ".claude/commands/wiki-init.md" "$TEMPLATE_URL/.claude/commands/wiki-init.md"
|
||||||
|
update_file ".claude/commands/wiki-capture.md" "$TEMPLATE_URL/.claude/commands/wiki-capture.md"
|
||||||
|
update_file ".claude/commands/wiki-update.md" "$TEMPLATE_URL/.claude/commands/wiki-update.md"
|
||||||
|
update_file ".claude/commands/wiki-recall.md" "$TEMPLATE_URL/.claude/commands/wiki-recall.md"
|
||||||
|
|
||||||
|
# wiki 的「使用者資料」:絕不碰
|
||||||
|
keep_file ".claude/wiki/status.md"
|
||||||
|
keep_file ".claude/wiki/mistakes.md"
|
||||||
|
keep_file ".claude/wiki/decisions-summary.md"
|
||||||
|
keep_file ".claude/wiki/.wikiignore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $HAS_SDD; then
|
||||||
|
# SDD 範本與 hook:可覆蓋
|
||||||
|
update_file "docs/3-specs/TEMPLATE-sdd/design.md" "$TEMPLATE_URL/docs/3-specs/TEMPLATE-sdd/design.md"
|
||||||
|
update_file "docs/3-specs/TEMPLATE-sdd/tasks.md" "$TEMPLATE_URL/docs/3-specs/TEMPLATE-sdd/tasks.md"
|
||||||
|
update_file "docs/2-architecture/decisions/TEMPLATE-adr.md" "$TEMPLATE_URL/docs/2-architecture/decisions/TEMPLATE-adr.md"
|
||||||
|
update_file ".claude/commands/sdd-check.md" "$TEMPLATE_URL/.claude/commands/sdd-check.md"
|
||||||
|
update_file ".claude/hooks/sdd-guard.sh" "$TEMPLATE_URL/.claude/hooks/sdd-guard.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 自我更新:把最新的 update.sh 也抓下來(含 install.sh)──
|
||||||
|
# 這兩支在 main/scripts/ 下,不在 template/。
|
||||||
|
update_file "scripts/update.sh" "$REPO_RAW/scripts/update.sh"
|
||||||
|
update_file "scripts/install.sh" "$REPO_RAW/scripts/install.sh"
|
||||||
|
|
||||||
|
chmod +x .claude/hooks/*.sh scripts/*.sh 2>/dev/null || true
|
||||||
|
|
||||||
|
# ── 使用者資料檔:絕不碰,但提醒「設定可能有新欄位要手動補」──
|
||||||
|
keep_file ".claude/settings.json"
|
||||||
|
keep_file "CLAUDE.md"
|
||||||
|
|
||||||
|
# ── 結果輸出 ───────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "─────────────────────────────────"
|
||||||
|
if [ ${#NEW[@]} -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "🆕 新功能(舊版沒有,已加入):"
|
||||||
|
for f in "${NEW[@]}"; do echo " + $f"; done
|
||||||
|
fi
|
||||||
|
if [ ${#UPDATED[@]} -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "⬆️ 已更新(覆蓋成新版):"
|
||||||
|
for f in "${UPDATED[@]}"; do echo " ~ $f"; done
|
||||||
|
fi
|
||||||
|
if [ ${#NEW[@]} -eq 0 ] && [ ${#UPDATED[@]} -eq 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "✨ 模板邏輯檔已全部最新,無需變動。"
|
||||||
|
fi
|
||||||
|
if [ ${#KEPT[@]} -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "🔒 完整保留(你的內容/設定,從未碰過):"
|
||||||
|
for f in "${KEPT[@]}"; do echo " = $f"; done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── settings.json 提醒:新模組 hook 可能要手動補 ──
|
||||||
|
if [ -f ".claude/settings.json" ]; then
|
||||||
|
MISSING=()
|
||||||
|
$HAS_WIKI && ! grep -q "session-start-recall.sh" .claude/settings.json && MISSING+=("SessionStart: session-start-recall.sh")
|
||||||
|
$HAS_WIKI && ! grep -q "wiki-secret-scan.sh" .claude/settings.json && MISSING+=("PreToolUse(Write|Edit): wiki-secret-scan.sh")
|
||||||
|
$HAS_SDD && ! grep -q "sdd-guard.sh" .claude/settings.json && MISSING+=("PreToolUse(Write|Edit): sdd-guard.sh")
|
||||||
|
if [ ${#MISSING[@]} -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "📌 settings.json 是你的設定(沒動),但偵測到缺以下 hook,請手動補上:"
|
||||||
|
for h in "${MISSING[@]}"; do echo " • $h"; done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🚀 更新完成:${LOCAL_VER} → ${REMOTE_VER}"
|
||||||
|
echo " 下次更新直接跑:bash scripts/update.sh"
|
||||||
|
echo " 改了什麼看:CHANGELOG.md"
|
||||||
|
echo ""
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.1.0
|
||||||
Reference in New Issue
Block a user