feat: 安裝結構收進 system-dev/(不污染用戶根目錄)+ 舊版自動遷移 + bump 1.9.0

工具產物原散在用戶根目錄(docs 七層、scripts),又把 wiki/VERSION 寄生在 CC 原生
.claude/ 裡,用戶分不清哪個 docs 是工具的。這版徹底收斂:除 .claude/(settings/
commands/hooks)與 CLAUDE.md 留根,工具所有資料收進 system-dev/。

對應 SDD: system-dev/docs/3-specs/install-layout/(內部記錄,依原則不推)。

- 新結構 system-dev/{VERSION,wiki/,docs/,scripts/};.claude/ 只剩 CC 機制檔
- wiki 改寫產物落點正式化:install 建 system-dev/wiki/cards/(.gitkeep)
- docs 雙語義拆開:工具文件→system-dev/docs/;用戶 raw source 維持原處只讀
- scripts 一開始就裝進 system-dev/scripts/
- 舊版自動遷移雙保險:update.sh 冪等搬移(wiki 含 .git、docs 白名單)
  + session-start hook 偵測舊結構未遷移時提示(low-code 用戶兜底)
- wiki-secret-scan 觸發路徑改 system-dev/wiki/**(否則新結構防護失效)
- 全套路徑引用同步:CLAUDE/SKILL/wiki-*/sdd-*/hooks/INDEX/README(中英)
- 沙盒驗證:遷移含 .git commit 一致、冪等、用戶自填 docs 保留;全 bash -n 過

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-26 15:13:43 +08:00
parent c95705c286
commit ecf1f882c6
27 changed files with 283 additions and 166 deletions
+55 -33
View File
@@ -27,6 +27,8 @@ t() { if [ "$IS_ZH" = "yes" ]; then printf '%s\n' "$1"; else printf '%s\n' "$2";
tn() { if [ "$IS_ZH" = "yes" ]; then printf '%s' "$1"; else printf '%s' "$2"; fi; }
REPO_URL="https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main/template"
# install.sh / update.sh 住在 main/scripts/(不在 template/)。
SCRIPTS_URL="https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main/scripts"
CREATED=()
SKIPPED=()
@@ -164,7 +166,7 @@ BLOCK
if [ "$IS_VAULT" = "yes" ]; then
cat <<BLOCK
- 這是 **${VAULT_TYPE} 筆記庫**:保留它原本的目錄與檔名慣例,**不得搬動、改名、重新分類** \`.md\` 檔,
以免破壞筆記軟體結構造成筆記不可讀。整理只在 \`.claude/wiki/\` 產出,**不動 raw source 本身**。
以免破壞筆記軟體結構造成筆記不可讀。整理只在 \`system-dev/wiki/\` 產出,**不動 raw source 本身**。
BLOCK
fi
else
@@ -191,7 +193,7 @@ BLOCK
if [ "$IS_VAULT" = "yes" ]; then
cat <<BLOCK
- This is a **${VAULT_TYPE} note vault**: keep its original directory and file-naming conventions. **Do not move, rename, or re-classify** \`.md\` files,
or you'll break the note-app structure and make notes unreadable. Curation output goes only into \`.claude/wiki/\`; **never touch the raw source itself**.
or you'll break the note-app structure and make notes unreadable. Curation output goes only into \`system-dev/wiki/\`; **never touch the raw source itself**.
BLOCK
fi
fi
@@ -218,26 +220,39 @@ download_if_missing() {
fi
}
# ── 共用結構(兩個模組都需要 docs 分類 + .claude──
create_dir "docs/1-vision"
create_dir "docs/2-architecture/decisions"
create_dir "docs/4-guides"
create_dir "docs/5-records/incidents"
create_dir "docs/5-records/test-reports"
create_dir "docs/6-user"
# ── 共用結構 ──────────────────────────────────────
# 工具自己的文件骨架收進 system-dev/docs/(不污染用戶根目錄、不跟用戶自己的 docs/ 混)。
# 注意語義分離:這裡的 system-dev/docs/ 是「工具文件」;用戶的 raw source(原始文件)
# 另有其處(見上方 vault 偵測),工具只讀、不搬。
# .claude/ 只留 CC 死綁的 commands/ + hooks/,工具資料一律不放這。
create_dir "system-dev/docs/1-vision"
create_dir "system-dev/docs/2-architecture/decisions"
create_dir "system-dev/docs/4-guides"
create_dir "system-dev/docs/5-records/incidents"
create_dir "system-dev/docs/5-records/test-reports"
create_dir "system-dev/docs/6-user"
create_dir ".claude/commands"
create_dir ".claude/hooks"
download_if_missing "docs/README.md" "$REPO_URL/docs/README.md"
download_if_missing "system-dev/docs/README.md" "$REPO_URL/system-dev/docs/README.md"
# 工具版號:放 system-dev/,不寄生 .claude/。
download_if_missing "system-dev/VERSION" "$REPO_URL/system-dev/VERSION"
# ── WIKI 模組 ─────────────────────────────────────
# wiki 是工具資料 → 放 system-dev/wiki/(不放 .claude/)。
# commands/ 與 hooks/ 是 CC 機制檔 → 維持 .claude/。
if $WANT_WIKI; then
create_dir ".claude/wiki"
download_if_missing ".claude/wiki/INDEX.md" "$REPO_URL/.claude/wiki/INDEX.md"
download_if_missing ".claude/wiki/TAXONOMY.md" "$REPO_URL/.claude/wiki/TAXONOMY.md"
download_if_missing ".claude/wiki/status.md" "$REPO_URL/.claude/wiki/status.md"
download_if_missing ".claude/wiki/mistakes.md" "$REPO_URL/.claude/wiki/mistakes.md"
download_if_missing ".claude/wiki/decisions-summary.md" "$REPO_URL/.claude/wiki/decisions-summary.md"
download_if_missing ".claude/wiki/.wikiignore" "$REPO_URL/.claude/wiki/.wikiignore"
create_dir "system-dev/wiki"
download_if_missing "system-dev/wiki/INDEX.md" "$REPO_URL/system-dev/wiki/INDEX.md"
download_if_missing "system-dev/wiki/TAXONOMY.md" "$REPO_URL/system-dev/wiki/TAXONOMY.md"
download_if_missing "system-dev/wiki/status.md" "$REPO_URL/system-dev/wiki/status.md"
download_if_missing "system-dev/wiki/mistakes.md" "$REPO_URL/system-dev/wiki/mistakes.md"
download_if_missing "system-dev/wiki/decisions-summary.md" "$REPO_URL/system-dev/wiki/decisions-summary.md"
download_if_missing "system-dev/wiki/.wikiignore" "$REPO_URL/system-dev/wiki/.wikiignore"
# wiki 改寫產物(AI 自讀定稿卡片)的正式落點:由工具建好,不靠用戶自救。
create_dir "system-dev/wiki/cards"
[ -f "system-dev/wiki/cards/.gitkeep" ] || { : > "system-dev/wiki/cards/.gitkeep"; CREATED+=("system-dev/wiki/cards/.gitkeep"); }
download_if_missing ".claude/commands/wiki-init.md" "$REPO_URL/.claude/commands/wiki-init.md"
download_if_missing ".claude/commands/wiki-capture.md" "$REPO_URL/.claude/commands/wiki-capture.md"
@@ -250,20 +265,27 @@ if $WANT_WIKI; then
# Coworkclaude.ai)整理 wiki 用的 skill:與 CC 的 /wiki-init 共用同一套規則
# (含 typed-edge、frontmatter 標籤、gloss)。沒這支 → claude.ai 來掃時身上沒規則。
download_if_missing "docs/SKILL.md" "$REPO_URL/docs/SKILL.md"
download_if_missing "system-dev/docs/SKILL.md" "$REPO_URL/system-dev/docs/SKILL.md"
fi
# ── SDD 模組 ──────────────────────────────────────
if $WANT_SDD; then
create_dir "docs/3-specs"
download_if_missing "docs/3-specs/TEMPLATE-sdd/design.md" "$REPO_URL/docs/3-specs/TEMPLATE-sdd/design.md"
download_if_missing "docs/3-specs/TEMPLATE-sdd/tasks.md" "$REPO_URL/docs/3-specs/TEMPLATE-sdd/tasks.md"
download_if_missing "docs/2-architecture/decisions/TEMPLATE-adr.md" "$REPO_URL/docs/2-architecture/decisions/TEMPLATE-adr.md"
create_dir "system-dev/docs/3-specs"
download_if_missing "system-dev/docs/3-specs/TEMPLATE-sdd/design.md" "$REPO_URL/system-dev/docs/3-specs/TEMPLATE-sdd/design.md"
download_if_missing "system-dev/docs/3-specs/TEMPLATE-sdd/tasks.md" "$REPO_URL/system-dev/docs/3-specs/TEMPLATE-sdd/tasks.md"
download_if_missing "system-dev/docs/2-architecture/decisions/TEMPLATE-adr.md" "$REPO_URL/system-dev/docs/2-architecture/decisions/TEMPLATE-adr.md"
download_if_missing ".claude/commands/sdd-check.md" "$REPO_URL/.claude/commands/sdd-check.md"
download_if_missing ".claude/hooks/sdd-guard.sh" "$REPO_URL/.claude/hooks/sdd-guard.sh"
fi
# ── 安裝/更新腳本:一開始就放進 system-dev/scripts/ ──
# 為什麼一開始就裝:之後要更新,用戶(或 CC)直接 `bash system-dev/scripts/update.sh`
# 不必每次都記那串 curl。腳本來源在 main/scripts/(不在 template/)。
create_dir "system-dev/scripts"
download_if_missing "system-dev/scripts/install.sh" "$SCRIPTS_URL/install.sh"
download_if_missing "system-dev/scripts/update.sh" "$SCRIPTS_URL/update.sh"
# ── 共用 hook:專案自訂禁令骨架(預設停用)────────
download_if_missing ".claude/hooks/pre-write-guard.sh" "$REPO_URL/.claude/hooks/pre-write-guard.sh"
@@ -355,22 +377,22 @@ if [ -f "CLAUDE.md" ]; then
## Wiki 讀取順序
| 檔案 | 時機 | 用途 |
|------|------|------|
| `.claude/wiki/status.md` | session 開始第一件事 | 當前進度 |
| `.claude/wiki/mistakes.md` | 做新功能前 | 已知誤解 |
| `.claude/wiki/decisions-summary.md` | 設計判斷時 | 架構決策 |
| `system-dev/wiki/status.md` | session 開始第一件事 | 當前進度 |
| `system-dev/wiki/mistakes.md` | 做新功能前 | 已知誤解 |
| `system-dev/wiki/decisions-summary.md` | 設計判斷時 | 架構決策 |
SNIP
else
cat <<'SNIP'
## Wiki reading order
| File | When | Purpose |
|------|------|---------|
| `.claude/wiki/status.md` | first thing at session start | current progress |
| `.claude/wiki/mistakes.md` | before building a new feature | known misconceptions |
| `.claude/wiki/decisions-summary.md` | when making design calls | architecture decisions |
| `system-dev/wiki/status.md` | first thing at session start | current progress |
| `system-dev/wiki/mistakes.md` | before building a new feature | known misconceptions |
| `system-dev/wiki/decisions-summary.md` | when making design calls | architecture decisions |
SNIP
fi
fi
if $WANT_SDD && ! grep -q "docs/3-specs" CLAUDE.md; then
if $WANT_SDD && ! grep -q "system-dev/docs/3-specs" CLAUDE.md; then
echo ""
t "📌 CLAUDE.md 已存在但缺少 SDD 鐵律,請手動加入:" \
"📌 CLAUDE.md exists but lacks the SDD iron rule — please add it manually:"
@@ -378,13 +400,13 @@ SNIP
if [ "$IS_ZH" = "yes" ]; then
cat <<'SNIP'
## 絕對鐵律
1. 任何 code 變動前必須有對應 SDDdocs/3-specs/[子系統]/design.md
1. 任何 code 變動前必須有對應 SDD(system-dev/docs/3-specs/[子系統]/design.md
找不到 → 停手問負責人,不要自行建立。
SNIP
else
cat <<'SNIP'
## Iron rule
1. Every code change must have a matching SDD (docs/3-specs/[subsystem]/design.md).
1. Every code change must have a matching SDD (system-dev/docs/3-specs/[subsystem]/design.md).
Not found → stop and ask the owner; do not create one on your own.
SNIP
fi
@@ -423,8 +445,8 @@ if $WANT_WIKI; then
" CC will scan your existing docs, apply .wikiignore, and build the wiki."
fi
if $WANT_SDD; then
t " 動 code 前先在 docs/3-specs/[子系統]/ 建 design.md(可用 /sdd-check 協助)" \
" Before touching code, create design.md under docs/3-specs/[subsystem]/ (use /sdd-check to help)"
t " 動 code 前先在 system-dev/docs/3-specs/[子系統]/ 建 design.md(可用 /sdd-check 協助)" \
" Before touching code, create design.md under system-dev/docs/3-specs/[subsystem]/ (use /sdd-check to help)"
fi
t " GitHub issueCC 可直接 /issue-handle 讀回自己 repo 的 issue(禁自動輪詢)" \
" GitHub issues: CC can use /issue-handle to read issues from its own repo (no auto-polling)"