2a8c259d08
🔴 修的病:這個框架 repo 自己的 5 份 SDD 全部被 .gitignore 擋在版控之外, 只活在一台硬碟上——clone 不到、雲端 CC 讀不到、沒備份。SDD 是進度真相源, 「框架 repo 沒吃自己的狗糧」。 依據 D22(已翻案):Gitea private 除機敏值外全 push,雲端工人靠 clone,docs 缺=斷糧; 只有 GitHub mirror 才嚴篩,而 docs 整包已在 github-publish-exclude.txt。 .gitignore 改法:整條擋 → 只擋子項(/*)+ 逐個放行真 SDD。 與 template/ 底下逐位元組相同的自裝副本(TEMPLATE-sdd/、SDD-LIFECYCLE.md)續擋。 新增 docs/3-specs/jdd-dual-profile/(status: draft,等 leo confirm 才升 active): JDD(PM 軌 root/journeys/角色權限/站號 sprint)與雙 profile 合成一卷, 33 條 task/6 phase,每條掛服務哪條 Gherkin(G1–G7)。 新增 hook 6 支、改既有 hook 1 支。**0 行實作**。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
147 lines
11 KiB
Markdown
147 lines
11 KiB
Markdown
# install-layout — Design
|
||
|
||
> 狀態:已採納
|
||
> 建立:2026-06-26 | 最後更新:2026-06-26
|
||
> 負責人:leo(uncle6me-web)
|
||
|
||
---
|
||
|
||
## 一句話說明
|
||
|
||
把工具安裝產物從「散落在用戶根目錄(docs/、scripts/、.claude/wiki、.claude/VERSION)」收斂成「只留 CC 死綁的 .claude/ + CLAUDE.md,其餘全進 system-dev/」,並為 wiki 改寫產物正式準備落點。
|
||
|
||
---
|
||
|
||
## 背景與問題
|
||
|
||
目標用戶是 low-code、只會叫 CC 做事的無技術用戶(見 memory user-profile-lowcode)。現行安裝有三個結構問題:
|
||
|
||
1. **污染用戶根目錄**:install 在根目錄鋪 `docs/`(七層子目錄)、update 時又生 `scripts/`,跟用戶自己的檔案混在一起,用戶分不清「哪個 docs 是工具的、哪個是我的」。
|
||
2. **工具資料寄生在 CC 原生資料夾**:`wiki/` 和 `VERSION` 放在 `.claude/` 裡。`.claude/` 是 CC 原生機制目錄,不該塞工具自己的資料與版號。
|
||
3. **wiki 改寫產物沒有正式落點**:`cards/`(改寫成 AI 自讀定稿 wiki 的落地處)install 從沒建立,導致實機(KB)自己長出 `.claude/wiki/cards/` 還自行 `git init`。位置該由工具準備,不靠用戶自救。
|
||
|
||
關鍵語義陷阱:現行 `docs/` 同時是「工具文件結構」與「用戶 raw source(原始文件來源)」。重構必須把這兩義拆開。
|
||
|
||
---
|
||
|
||
## 範圍
|
||
|
||
### 包含(In Scope)
|
||
- 新增 `system-dev/` 作為工具所有「資料」的根:`system-dev/{VERSION,wiki/,docs/,scripts/}`。
|
||
- `.claude/` 只保留 CC 死綁的三樣:`settings.json`、`commands/`、`hooks/`。
|
||
- `wiki/`(含 cards/)、`VERSION`、工具的 `docs/`、`scripts/` 全部移到 `system-dev/`。
|
||
- install.sh 正式建立 `system-dev/wiki/cards/`(放 `.gitkeep` 空桶佔位)。
|
||
- 舊用戶遷移:update.sh 自動遷移 + session-start hook 自我防呆(雙保險)。
|
||
- 同步更新所有路徑引用(CLAUDE.md、SKILL.md、wiki-init、sdd-check、wiki-capture、sdd-guard、session-start-recall、INDEX、decisions-summary、README)。
|
||
|
||
### 不包含(Out of Scope)
|
||
- **不動用戶 raw source**:用戶自己的 `docs/`、Logseq `pages/+journals/`、Obsidian vault 根——工具只讀、不搬、不改名。
|
||
- **不搬 commands/ 與 hooks/ 出 .claude/**:CC slash command 與 hook 註冊路徑死綁 `.claude/`(hooks 經討論決定務實留 .claude/)。
|
||
- **不改 CLAUDE.md 位置**:CC 開 session 只讀根目錄/.claude 的 CLAUDE.md,留根。
|
||
- 不重寫 wiki 內容本身(只準備落點與路徑;既有卡片內容遷移不改寫)。
|
||
|
||
---
|
||
|
||
## 設計
|
||
|
||
### 架構概覽
|
||
|
||
```
|
||
用戶專案/
|
||
├── CLAUDE.md ← CC 原生,留根
|
||
├── .claude/ ← 只放 CC 機制檔
|
||
│ ├── settings.json ← CC 原生(hook 在此註冊)
|
||
│ ├── commands/*.md ← slash 指令,CC 死綁此路徑
|
||
│ └── hooks/*.sh ← 留 .claude/(務實決定)
|
||
└── system-dev/ ← 工具所有資料(新)
|
||
├── VERSION ← 工具版號(從 .claude/VERSION 搬出)
|
||
├── wiki/ ← 工具 wiki(從 .claude/wiki/ 搬出)
|
||
│ ├── INDEX.md TAXONOMY.md status.md mistakes.md decisions-summary.md .wikiignore
|
||
│ └── cards/ ← 【新】改寫產物落點,install 建好,.gitkeep 佔位
|
||
├── docs/ ← 工具文件(從根 docs/ 搬出)
|
||
│ ├── README.md SKILL.md
|
||
│ └── 1-vision/ 2-architecture/ 3-specs/ 4-guides/ 5-records/ 6-user/
|
||
└── scripts/ ← install.sh + update.sh,一開始就裝
|
||
```
|
||
|
||
### 關鍵決策
|
||
|
||
| 決策 | 選擇 | 原因 | 放棄的選項 |
|
||
|------|------|------|----------|
|
||
| 工具資料落點 | 收進 `system-dev/` | 不污染用戶根目錄;用戶一眼分清工具 vs 自己的檔 | 散在根目錄(現狀,壞習慣) |
|
||
| 資料夾命名 | `system-dev/`(明碼) | 用戶 ls 看得到、好找 | `.sdt/`、`.system-dev/`(隱藏,low-code 用戶不易發現) |
|
||
| wiki/VERSION | 搬出 .claude/ | 工具資料不該寄生 CC 原生目錄 | 留 .claude/(現狀,職責混淆) |
|
||
| commands/hooks | 留 .claude/ | CC 機制死綁;hooks 搬走只多一層路徑、無實益 | 全搬 system-dev/(settings.json 走不了,得留跳板) |
|
||
| CLAUDE.md | 留根 | CC 自動讀,搬走整套導航/鐵律失效 | 搬 system-dev/(要留極薄跳板,等於沒搬) |
|
||
| docs 雙語義 | 拆開:工具→system-dev/docs/,raw source 維持用戶處 | 解決「哪個 docs 是誰的」 | 全搬(會誤搬用戶內容)/ 全留(污染依舊) |
|
||
| cards/ 落點 | install 正式建 + .gitkeep | 位置由工具準備,不靠用戶自救 | 不建(現狀,用戶自己長、自行 git init) |
|
||
| 舊用戶遷移 | update 自動遷移 + hook 防呆雙保險 | low-code 用戶不會手動遷;不遷會默默壞 | 只靠 update(沒跑的人壞)/ 只靠手動(用戶不會做) |
|
||
| 版本語意 | 1.9.0(中版號 + 自動遷移、向下相容到能升上來) | 提供自動遷移即非破壞性手動 | 2.0.0(若要求用戶手動遷才算) |
|
||
| 舊腳本升級撞 404(1.9.1) | ① 發佈源保留 `template/.claude/VERSION` 相容墊片 ② 新腳本驗 REMOTE_VER 須像版號 | 1.8.x 舊腳本寫死抓舊 VERSION 路徑,搬走後 curl 回「404」字串、被當內容寫進 VERSION;墊片讓舊腳本不 404,格式驗證讓未來任何路徑變動都不污染 VERSION。**bump 時兩個 VERSION 檔須同步**(system-dev/VERSION 權威 + .claude/VERSION 墊片) | 不留墊片(舊用戶撞 404);只靠 README 改 curl(救不了已跑本機舊腳本的人) |
|
||
| CLAUDE.md 等用戶檔遷移後仍寫舊路徑(1.9.2) | session-start hook 偵測 + 提示 CC 代修 | 遷移搬檔案位置,但 update.sh 鐵則「絕不碰 CLAUDE.md」(用戶資料)→ CLAUDE.md 內 `.claude/wiki` 變死引用,CC 照它找錯位置。讓腳本盲 sed 改用戶 CLAUDE.md 風險高(可能誤傷用戶自寫內容、破壞鐵則),改由 CC(懂語義、知道 raw source 的 `docs/` 要保留)代改 | 腳本自動 sed 改(誤傷風險 + 破鐵則);只寫 README(low-code 用戶不看) |
|
||
| 重複 install 製造 wiki 並存(1.10.1) | **職責切分:install 只管「全新安裝」,一切已裝過的後續(更新/遷移/補新檔)歸 update。** ① install 偵測「裝過沒」(system-dev/ 或 .claude/wiki/ 或 .claude/VERSION 任一存在,不分新舊版)→ 不動任何東西,導去 update 並 exit ② update 的 migrate_dir:目的地已存在但舊位置仍有真資料 → 記 COEXIST 警告「並存需合併」,不靜默跳過、不自動合併 ③ install↔update 互相導向(update 遇全新專案也導回 install),閉環無死結 | 根因不是「舊結構」而是「重複 install」:判準該是裝過沒、不是哪個版本。用戶先 install(建空殼)→ 再 update(遷移被冪等擋掉)→ 真資料卡舊位置、空殼佔新位置、並存。切乾淨職責後,install 永不在已裝專案動手,從源頭杜絕並存 | 只擋舊結構(新版重裝照樣亂);腳本自動合併(覆蓋風險);migrate 靜默跳過(並存無聲、用戶不知資料分裂) |
|
||
|
||
### 介面定義:遷移行為(雙保險)
|
||
|
||
**第 1 層 — update.sh 自動遷移(冪等)**
|
||
- 偵測舊位置存在 → 搬到 system-dev/:
|
||
- `.claude/wiki/` → `system-dev/wiki/`(含 cards/、含 wiki/.git,用保留 .git 的搬法)
|
||
- `.claude/VERSION` → `system-dev/VERSION`
|
||
- 根 `docs/` 中**工具自己鋪的白名單路徑**(README.md、SKILL.md、3-specs/、2-architecture/、1-vision/、4-guides/、5-records/、6-user/)→ `system-dev/docs/`
|
||
- **用戶自填的 docs 內容不搬**(白名單外的一律不動)
|
||
- system-dev/ 已存在對應檔 → 略過(可重複跑)
|
||
- 印出「已遷移 X → system-dev/」
|
||
|
||
**第 2 層 — session-start-recall.sh 自我防呆**
|
||
- 開 session 檢查舊路徑 `.claude/wiki/` 是否還在:
|
||
- 在 → 印「⚠️ 偵測到舊結構未遷移,跑 update.sh 或叫 CC 幫你遷移」
|
||
- CC 見此訊息即知該遷,可當場用檔案工具搬
|
||
|
||
### 資料模型:受影響路徑引用清單
|
||
|
||
| 檔案 | 改動類別 |
|
||
|------|---------|
|
||
| scripts/install.sh | create_dir/download 落點 docs/→system-dev/docs/、wiki→system-dev/wiki/、VERSION、新增 cards/、scripts/ 落點 |
|
||
| scripts/update.sh | update_file/keep_file 路徑、自我更新路徑、VERSION 讀點、**新增遷移段** |
|
||
| template/CLAUDE.md + 根 CLAUDE.md | 鐵律/速查表/wiki 讀取表路徑;raw source 宣告維持 |
|
||
| template/docs/SKILL.md | cards/ 落點 → system-dev/wiki/cards/;raw source 偵測語義維持 |
|
||
| .claude/commands/wiki-init.md(+template) | cards/ 落點、工具 docs 示意、SKILL 引用;raw source 偵測維持 |
|
||
| .claude/commands/wiki-capture.md、sdd-check.md(+template) | docs/2-architecture、docs/3-specs → system-dev/docs/ |
|
||
| .claude/hooks/sdd-guard.sh(+template) | 7 處 docs/3-specs → system-dev/docs/3-specs |
|
||
| .claude/hooks/session-start-recall.sh | STATUS_FILE 路徑 + 新增防呆檢查 |
|
||
| .claude/wiki/INDEX.md、decisions-summary.md(+template) | docs/2-architecture 引用 |
|
||
| README.md、README.en.md | 目錄樹示意、安裝後說明 |
|
||
|
||
---
|
||
|
||
## 技術限制
|
||
|
||
- **bash 3.2 相容**(macOS 內建):腳本改動後必須 `bash -n` 過,且多位元組字元旁變數一律 `${VAR}` 包好(1.7.0/1.8.2 崩潰教訓)。
|
||
- **不可破壞 wiki/.git**:實機 KB 的 wiki 自帶獨立 git repo(192 張卡),遷移時用保留 .git 的搬法。
|
||
- **必須相容 CC 原生機制**:commands/hooks/settings.json/CLAUDE.md 路徑不可違反 CC 載入慣例。
|
||
- **遷移必須冪等**:update.sh 可被重複跑(含「以為沒更新再跑一次」)而不出錯。
|
||
- **curl | bash 串流安全**:update.sh/install.sh 走遠端串流執行,不可在多位元組邊界出 unbound variable。
|
||
|
||
---
|
||
|
||
## 驗收標準
|
||
|
||
完成的定義:
|
||
- [ ] 新裝(install.sh):根目錄只出現 `.claude/` + `CLAUDE.md`,其餘全在 `system-dev/`;`system-dev/wiki/cards/` 存在且有 .gitkeep。
|
||
- [ ] `system-dev/VERSION` 存在且 .claude/ 下無 VERSION。
|
||
- [ ] 舊用戶跑 update.sh:舊 `.claude/wiki/`、根工具 `docs/`、`scripts/` 自動遷入 system-dev/,wiki/.git 完好,可重複跑不出錯。
|
||
- [ ] 未遷移用戶開 session:hook 印出防呆提示,不默默失敗。
|
||
- [ ] 所有路徑引用無殘留死連結(grep 不到非 raw-source 語義的舊 `docs/3-specs`、`.claude/wiki` 寫死路徑)。
|
||
- [ ] raw source 語義引用維持指向用戶原始文件(未被誤改成 system-dev/)。
|
||
- [ ] `bash -n` 通過 install.sh 與 update.sh。
|
||
- [ ] 實機 KB 套用後:開 session 接關正常、/wiki-init 寫入 system-dev/wiki/cards/、192 張卡與其 .git 完整。
|
||
|
||
---
|
||
|
||
## 相關文件
|
||
|
||
- memory: user-profile-lowcode(目標用戶輪廓)
|
||
- memory: sdd-rule-applies-to-this-repo(本 repo 也守 SDD 鐵律)
|
||
- 前置 hotfix:1.8.2(update.sh bash 3.2 崩潰修復,已 push)
|
||
- 前置:1.8.1(補裝 Cowork SKILL.md,已 push)
|