From ecf1f882c695dbe5fd563032fee1d61b83c0e8c0 Mon Sep 17 00:00:00 2001 From: richblack Date: Fri, 26 Jun 2026 15:13:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=89=E8=A3=9D=E7=B5=90=E6=A7=8B?= =?UTF-8?q?=E6=94=B6=E9=80=B2=20system-dev/(=E4=B8=8D=E6=B1=A1=E6=9F=93?= =?UTF-8?q?=E7=94=A8=E6=88=B6=E6=A0=B9=E7=9B=AE=E9=8C=84)+=20=E8=88=8A?= =?UTF-8?q?=E7=89=88=E8=87=AA=E5=8B=95=E9=81=B7=E7=A7=BB=20+=20bump=201.9.?= =?UTF-8?q?0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 工具產物原散在用戶根目錄(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) --- CHANGELOG.md | 14 +++ README.en.md | 18 +-- README.md | 66 ++++++----- docs/SKILL.md | 16 +-- scripts/install.sh | 88 ++++++++------ scripts/update.sh | 107 ++++++++++++++---- template/.claude/VERSION | 1 - template/.claude/commands/sdd-check.md | 6 +- template/.claude/commands/wiki-capture.md | 10 +- template/.claude/commands/wiki-init.md | 22 ++-- template/.claude/commands/wiki-recall.md | 6 +- template/.claude/hooks/sdd-guard.sh | 16 +-- .../.claude/hooks/session-start-recall.sh | 14 ++- template/.claude/hooks/wiki-secret-scan.sh | 8 +- template/CLAUDE.md | 32 +++--- template/system-dev/VERSION | 1 + .../2-architecture/decisions/TEMPLATE-adr.md | 0 .../docs/3-specs/TEMPLATE-sdd/design.md | 0 .../docs/3-specs/TEMPLATE-sdd/tasks.md | 0 template/{ => system-dev}/docs/README.md | 0 template/{ => system-dev}/docs/SKILL.md | 16 +-- .../{.claude => system-dev}/wiki/.wikiignore | 0 .../{.claude => system-dev}/wiki/INDEX.md | 4 +- .../{.claude => system-dev}/wiki/TAXONOMY.md | 0 .../wiki/decisions-summary.md | 4 +- .../{.claude => system-dev}/wiki/mistakes.md | 0 .../{.claude => system-dev}/wiki/status.md | 0 27 files changed, 283 insertions(+), 166 deletions(-) delete mode 100644 template/.claude/VERSION create mode 100644 template/system-dev/VERSION rename template/{ => system-dev}/docs/2-architecture/decisions/TEMPLATE-adr.md (100%) rename template/{ => system-dev}/docs/3-specs/TEMPLATE-sdd/design.md (100%) rename template/{ => system-dev}/docs/3-specs/TEMPLATE-sdd/tasks.md (100%) rename template/{ => system-dev}/docs/README.md (100%) rename template/{ => system-dev}/docs/SKILL.md (94%) rename template/{.claude => system-dev}/wiki/.wikiignore (100%) rename template/{.claude => system-dev}/wiki/INDEX.md (94%) rename template/{.claude => system-dev}/wiki/TAXONOMY.md (100%) rename template/{.claude => system-dev}/wiki/decisions-summary.md (61%) rename template/{.claude => system-dev}/wiki/mistakes.md (100%) rename template/{.claude => system-dev}/wiki/status.md (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 674b9aa..35a9dda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,20 @@ --- +## 1.9.0 — 安裝結構收進 `system-dev/`(不再污染用戶根目錄)+ 舊版自動遷移 + +工具產物原本散在用戶根目錄(`docs/` 七層、update 時的 `scripts/`),又把 `wiki/`、`VERSION` 寄生在 CC 原生的 `.claude/` 裡,用戶分不清「哪個 docs 是工具的、哪個是我的」。這版徹底收斂:除了 CC 死綁的 `.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`),不再讓用戶自己長出來、自行 git init。 +- **docs 雙語義拆開**:工具文件 → `system-dev/docs/`;**用戶 raw source(原始文件來源)維持原處**(用戶的 `docs/`、Logseq `pages/+journals/`、Obsidian vault),工具只讀、不搬。 +- **scripts 一開始就裝**:install 把 install.sh/update.sh 放進 `system-dev/scripts/`,之後更新直接 `bash system-dev/scripts/update.sh`。 +- **舊版自動遷移(雙保險)**:① update.sh 偵測舊位置 → 冪等搬進 `system-dev/`(wiki 含 `cards/` 與內含 `.git` 一起搬,docs 只搬工具白名單、不動用戶自填內容);② session-start hook 偵測到舊結構未遷移 → 出聲提示,CC 可當場代為遷移。給「只會叫 CC 做事」的 low-code 用戶兜底。 +- **機敏防護路徑跟進**:`wiki-secret-scan.sh` 觸發路徑改 `system-dev/wiki/**`(否則新結構下寫入不啟動、防護失效)。 +- 全套路徑引用同步更新:CLAUDE.md、SKILL.md、wiki-init、wiki-recall、wiki-capture、sdd-check、sdd-guard、session-start-recall、INDEX、decisions-summary、README(中英)。 + +> **升級提醒**:舊用戶跑一次 `update.sh` 即自動遷移;沒跑也會在開 session 時被 hook 提示。屬向下相容的中版號(非破壞性手動遷移)。 + ## 1.8.2 — 修 update.sh 在 `curl | bash` 下崩潰(bash 3.2 多位元組字元,1.7.0 漏修到的同類 bug) 1.7.0 修了 install.sh 的「多位元組字元旁變數要用 `${VAR}` 包」,但 update.sh 第 54 行漏網: diff --git a/README.en.md b/README.en.md index 8cdac4d..6b8112e 100644 --- a/README.en.md +++ b/README.en.md @@ -13,7 +13,7 @@ This template solves both problems with two systems: | System | What it solves | Core mechanism | |--------|----------------|----------------| | **SDD system** | Global view, think before doing | No code change without a `design.md` + `tasks.md` first | -| **LLM Wiki** | Memory that compounds, ordered docs | Two spaces: raw source (human-written) + `.claude/wiki/` (AI-curated) | +| **LLM Wiki** | Memory that compounds, ordered docs | Two spaces: raw source (human-written) + `system-dev/wiki/` (AI-curated) | > **Not just code projects, not just Claude Code.** LLM Wiki now also recognizes **Logseq / Obsidian vaults** — > at install time it auto-detects which kind of folder you're in, writes the matching "raw source" into `CLAUDE.md`, @@ -92,7 +92,7 @@ It first compares your version with the latest, tells you **which new features y | 🔒 **Never touch** your content and settings | `wiki/status.md`, `mistakes.md`, `decisions-summary.md`, `.wikiignore`, `settings.json`, `CLAUDE.md` | > **Why use curl the first time?** Old installs don't have `update.sh` locally yet, so the first run has to fetch it from the remote. -> After running, it installs itself to `scripts/update.sh`, so **next time just run** `bash scripts/update.sh` — no more curl. +> After running, it installs itself to `system-dev/scripts/update.sh`, so **next time just run** `bash system-dev/scripts/update.sh` — no more curl. Updates only touch "installed modules" (wiki installed → wiki updated; SDD installed → SDD updated), detected automatically. If `settings.json` is missing a hook that only the new version has, it won't change your settings for you — but it will **list them at the end** as a reminder to add them manually (it never edits your settings without asking). @@ -113,7 +113,7 @@ Now `install.sh` **auto-detects the folder type** before creating `CLAUDE.md`, a | Neither | Regular project | `docs/` (original behavior) | The declaration written into `CLAUDE.md` is **an instruction for the AI** — it tells the curator "here's where the raw source is, read only from there when curating the wiki", -and for vaults it **explicitly forbids moving, renaming, or re-classifying `.md` files**; curation output always goes only into `.claude/wiki/`. +and for vaults it **explicitly forbids moving, renaming, or re-classifying `.md` files**; curation output always goes only into `system-dev/wiki/`. This way, even with a note vault, the original structure stays intact and your notes never become unreadable. > **Already have a `CLAUDE.md`?** It's never overwritten (the "don't touch what exists" principle). Instead, the declaration you should add is **listed at the end** of the install for you to paste manually. @@ -123,16 +123,16 @@ This way, even with a note vault, the original structure stays intact and your n ## Cowork can curate wikis too The wiki curator is no longer limited to Claude Code in the terminal — **claude.ai's Cowork** can do it too. -`docs/SKILL.md` provides a skill for Cowork (`wiki-cowork-scan`) that **shares the same rules** as CC's `/wiki-init` and `/wiki-capture`: +`system-dev/docs/SKILL.md` provides a skill for Cowork (`wiki-cowork-scan`) that **shares the same rules** as CC's `/wiki-init` and `/wiki-capture`: -- Scans every folder under `~/Documents` that has system-dev-template installed (i.e. has a `.claude/wiki/`) +- Scans every folder under `~/Documents` that has system-dev-template installed (i.e. has a `system-dev/wiki/`) - Uses the **same detection logic as `install.sh`** to decide whether each folder is a regular project / Logseq / Obsidian -- Reads only the raw source and only appends to `.claude/wiki/` (no overwrite, no delete); **never touches** raw source, `CLAUDE.md`, `logseq/`, `.obsidian/`, `assets/` +- Reads only the raw source and only appends to `system-dev/wiki/` (no overwrite, no delete); **never touches** raw source, `CLAUDE.md`, `logseq/`, `.obsidian/`, `assets/` **CC and Cowork share an identical output format**, so whatever one curates, the other sees and skips or supplements — no duplication, no overwriting. Great for a scheduled Cowork run that keeps every wiki on your machine up to date automatically. -> To use it: give `docs/SKILL.md` to your Cowork as a skill reference, then tell it "curate the wiki". +> To use it: give `system-dev/docs/SKILL.md` to your Cowork as a skill reference, then tell it "curate the wiki". --- @@ -189,7 +189,7 @@ Norms are no longer just soft reminders in `CLAUDE.md`; there's a backstop: |------|------| | `session-start-recall.sh` | Auto-injects the key points of `status` at session start — doesn't rely on CC remembering | | `sdd-guard.sh` | Touching a code file with no SDD → block (exit 2); the automated version of `/sdd-check` | -| `wiki-secret-scan.sh` | A sensitive value about to be written into `.claude/wiki/` → block (exit 2); a mechanical backstop for passwords/keys/PII | +| `wiki-secret-scan.sh` | A sensitive value about to be written into `system-dev/wiki/` → block (exit 2); a mechanical backstop for passwords/keys/PII | | `pre-write-guard.sh` | Skeleton for project-specific bans (disabled by default; takes effect once you fill in a pattern) | --- @@ -200,7 +200,7 @@ Like `.gitignore`, it keeps content you don't want in the wiki (passwords, keys, | Layer | Mechanism | What it blocks | Nature | |-------|-----------|----------------|--------| -| **L1** | `.claude/wiki/.wikiignore` (glob) | An entire sensitive file is not indexed | Protocol (CC complies) | +| **L1** | `system-dev/wiki/.wikiignore` (glob) | An entire sensitive file is not indexed | Protocol (CC complies) | | **L2** | Inline markers ``…`` | A section within a file is not indexed | Protocol (CC complies) | | **L3** | `wiki-secret-scan.sh` hook | A sensitive value actually being written into the wiki → exit 2 blocks it | **Hard interception (mechanical detection)** | diff --git a/README.md b/README.md index 9c5710e..be44842 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ CC 是個優秀的工程師,但不是個好的專案經理。它會猛衝完 | 系統 | 解決什麼 | 核心機制 | |------|---------|---------| | **SDD 系統** | 全局觀、先想再做 | 動手前必須有 design.md + tasks.md | -| **LLM Wiki** | 記憶累積、文件有序 | 雙空間:原始文件(人寫)+ .claude/wiki/(AI 整理)| +| **LLM Wiki** | 記憶累積、文件有序 | 雙空間:原始文件(人寫)+ system-dev/wiki/(AI 整理)| > **不只程式碼專案、不只 Claude Code。** LLM Wiki 現在也認得 **Logseq / Obsidian vault**—— > 安裝時自動偵測你在哪種資料夾,把對應的「原始文件來源」寫進 `CLAUDE.md`,整理 wiki 時只讀那裡、 @@ -91,7 +91,7 @@ curl -sSL https://raw.githubusercontent.com/uncle6me-web/system-dev-template/mai | 🔒 **完全不碰**你的內容與設定 | `wiki/status.md`、`mistakes.md`、`decisions-summary.md`、`.wikiignore`、`settings.json`、`CLAUDE.md` | > **為什麼第一次要用 curl?** 舊版本機還沒有 `update.sh`,所以第一次得從遠端抓它下來跑。 -> 跑完它會把自己也裝進 `scripts/update.sh`,**之後更新直接跑** `bash scripts/update.sh` 就好,不用再 curl。 +> 跑完它會把自己也裝進 `system-dev/scripts/update.sh`,**之後更新直接跑** `bash system-dev/scripts/update.sh` 就好,不用再 curl。 更新只會動「已安裝的模組」(裝了 wiki 就更新 wiki,裝了 SDD 就更新 SDD),偵測自動完成。 若 `settings.json` 缺了新版才有的 hook,它不會幫你改設定,但會在結尾**列出來提醒你手動補**(不擅自動你的設定)。 @@ -112,7 +112,7 @@ LLM Wiki 原本假設「原始文件放在 `docs/`」,但 Logseq、Obsidian | 都沒有 | 一般專案 | `docs/`(維持原行為)| 寫進 `CLAUDE.md` 的這段宣告是**給 AI 讀的指令**——它告訴整理者「原始文件在哪、整理 wiki 時只讀那裡」, -而且對 vault **明令不得搬動、改名、重新分類 `.md`**,整理結果一律只寫進 `.claude/wiki/`。 +而且對 vault **明令不得搬動、改名、重新分類 `.md`**,整理結果一律只寫進 `system-dev/wiki/`。 這樣面對筆記 vault 也不會破壞它原本的結構,筆記不會變得不可讀。 > **已有 `CLAUDE.md`?** 一律不覆蓋(維持「已有的不動」原則),改在安裝結尾**列出該補的宣告**提醒你手動貼。 @@ -122,44 +122,54 @@ LLM Wiki 原本假設「原始文件放在 `docs/`」,但 Logseq、Obsidian ## Cowork 也能整理 wiki 整理 wiki 的人不再只有終端機裡的 Claude Code——**claude.ai 的 Cowork** 也可以。 -`docs/SKILL.md` 提供一個給 Cowork 用的 skill(`wiki-cowork-scan`),它與 CC 的 `/wiki-init`、`/wiki-capture` +`system-dev/docs/SKILL.md` 提供一個給 Cowork 用的 skill(`wiki-cowork-scan`),它與 CC 的 `/wiki-init`、`/wiki-capture` **共用同一套規則**: -- 掃描 `~/Documents` 下所有裝了 system-dev-template(含 `.claude/wiki/`)的資料夾 +- 掃描 `~/Documents` 下所有裝了 system-dev-template(含 `system-dev/wiki/`)的資料夾 - 用**和 `install.sh` 一致的偵測邏輯**判斷每個資料夾是一般專案 / Logseq / Obsidian -- 只讀 raw source、只往 `.claude/wiki/` 增補(不覆蓋、不刪除),**絕不動** raw source、`CLAUDE.md`、`logseq/`、`.obsidian/`、`assets/` +- 只讀 raw source、只往 `system-dev/wiki/` 增補(不覆蓋、不刪除),**絕不動** raw source、`CLAUDE.md`、`logseq/`、`.obsidian/`、`assets/` **CC 與 Cowork 輸出格式相同**,任一方整理過的內容,另一方看到就跳過或補充,不重複也不覆蓋。 適合掛在 Cowork 的定期排程,讓本機所有 wiki 自動保持更新。 -> 想用:把 `docs/SKILL.md` 提供給你的 Cowork 當 skill 參考,再對它說「整理 wiki」即可。 +> 想用:把 `system-dev/docs/SKILL.md` 提供給你的 Cowork 當 skill 參考,再對它說「整理 wiki」即可。 --- -## 目錄說明 +## 安裝後,你的專案會長這樣 + +> 設計原則:除了 CC 原生的 `.claude/` 和 `CLAUDE.md` 留在根目錄,**工具的所有資料都收進 `system-dev/`**, +> 不在你的根目錄撒一堆資料夾、也不跟你自己的 `docs/` 混在一起。 + +``` +你的專案/ +├── CLAUDE.md ← 導航牌(CC 開 session 自動讀,必須留根) +├── .claude/ ← 只放 CC 原生機制檔 +│ ├── settings.json ← 掛 hooks +│ ├── commands/ ← Slash commands(/wiki-init 等) +│ └── hooks/ ← 硬攔截(接關 + SDD 協議 + wiki 機敏掃描) +├── system-dev/ ← 工具所有資料收這裡 +│ ├── VERSION +│ ├── wiki/ ← CC 的記憶空間(含 cards/ 改寫產物落點、.wikiignore) +│ ├── docs/ ← 文件結構(六層分類 + SKILL.md) +│ └── scripts/ ← install.sh / update.sh(裝好就在這,下次直接跑) +└── (你自己的檔案 / docs / 筆記 vault —— 工具只讀、不搬、不碰) +``` + +## 這個 repo 自己的目錄 ``` system-dev-template/ -├── template/ ← 複製到新專案的骨架 -│ ├── CLAUDE.md ← 填空版導航牌 -│ ├── docs/ ← 文件結構(六層分類) -│ └── .claude/ -│ ├── wiki/ ← CC 的記憶空間(含 .wikiignore 機敏排除) -│ ├── commands/ ← Slash commands -│ ├── hooks/ ← 硬攔截(接關 + SDD 協議 + wiki 機敏掃描) -│ └── settings.json ← 掛 hooks(install.sh 依模組組裝) -│ +├── template/ ← 發佈源:install/update 從這裡抓檔 +│ ├── CLAUDE.md ← 填空版導航牌(落到用戶根目錄) +│ ├── .claude/ ← commands/ + hooks/(落到用戶 .claude/) +│ └── system-dev/ ← VERSION + wiki/ + docs/(落到用戶 system-dev/) ├── skills/ -│ └── llm-wiki/ ← 複製到 Legacy-Workspace/.claude/skills/ -│ +│ └── llm-wiki/ ← 複製到 Legacy-Workspace/.claude/skills/ ├── scripts/ -│ ├── install.sh ← 已有專案接入腳本 -│ └── update.sh ← 舊版一鍵更新(只換模板,不碰你的資料) -│ -└── docs/ ← 這個 repo 自己的說明 - ├── why.md ← 設計理念 - ├── wishlist.md ← 待補功能與已完成記錄 - └── SKILL.md ← 給 claude.ai Cowork 的 wiki 整理 skill(wiki-cowork-scan) +│ ├── install.sh ← 已有專案接入腳本 +│ └── update.sh ← 舊版一鍵更新(含舊結構自動遷移) +└── docs/ ← 這個 repo 自己的說明(why.md、wishlist.md…) ``` --- @@ -189,7 +199,7 @@ system-dev-template/ |------|------| | `session-start-recall.sh` | 開 session 自動注入 status 重點,不靠 CC 自覺 | | `sdd-guard.sh` | 動 code 檔但沒有任何 SDD → 攔(exit 2),對應 `/sdd-check` 的自動版 | -| `wiki-secret-scan.sh` | 機敏值要寫進 `.claude/wiki/` → 攔(exit 2),密碼/金鑰/個資的機械底線 | +| `wiki-secret-scan.sh` | 機敏值要寫進 `system-dev/wiki/` → 攔(exit 2),密碼/金鑰/個資的機械底線 | | `pre-write-guard.sh` | 專案自訂禁令範本骨架(預設停用,填 pattern 才生效)| --- @@ -200,7 +210,7 @@ system-dev-template/ | 層 | 機制 | 擋什麼 | 性質 | |----|------|--------|------| -| **L1** | `.claude/wiki/.wikiignore`(glob) | 整個機敏檔不編入 | 協議(CC 遵守)| +| **L1** | `system-dev/wiki/.wikiignore`(glob) | 整個機敏檔不編入 | 協議(CC 遵守)| | **L2** | 行內標記 ``…`` | 檔案內某段不編入 | 協議(CC 遵守)| | **L3** | `wiki-secret-scan.sh` hook | 機敏值真的寫進 wiki → exit 2 擋 | **硬攔截(機械偵測)**| diff --git a/docs/SKILL.md b/docs/SKILL.md index 647f78b..8977433 100644 --- a/docs/SKILL.md +++ b/docs/SKILL.md @@ -12,7 +12,7 @@ description: "掃描本機 Documents 下所有裝了 system-dev-template 的資 | 層 | 規則 | |------------|-------------------------------------------| | raw source | 只讀,不動 | -| `.claude/wiki/` | 唯一輸出地點,只增不覆 | +| `system-dev/wiki/` | 唯一輸出地點,只增不覆 | | `CLAUDE.md` | 不動 | | `logseq/`、`.obsidian/`、`assets/` | 絕對不動 | @@ -22,12 +22,12 @@ description: "掃描本機 Documents 下所有裝了 system-dev-template 的資 ## 第一步:發現所有目標資料夾 -掃描 `~/Documents`(遞迴深度 3 層),找出所有含 `.claude/wiki/` 的資料夾。 +掃描 `~/Documents`(遞迴深度 3 層),找出所有含 `system-dev/wiki/` 的資料夾。 ``` ~/Documents/ - project-a/.claude/wiki/ ← ✅ 目標 - Logseq/.claude/wiki/ ← ✅ 目標 + project-a/system-dev/wiki/ ← ✅ 目標 + Logseq/system-dev/wiki/ ← ✅ 目標 其他資料夾/ ← ❌ 跳過 ``` @@ -37,7 +37,7 @@ description: "掃描本機 Documents 下所有裝了 system-dev-template 的資 ## 第二步:對每個資料夾偵測 vault 類型 -進入每個目標資料夾的**根目錄**(`.claude/wiki/` 的上兩層),依序判斷: +進入每個目標資料夾的**根目錄**(`system-dev/wiki/` 的上兩層),依序判斷: ### 判斷順序(與 install.sh 一致) @@ -60,7 +60,7 @@ else ## 第三步:讀取現有 wiki 狀態 -進入 `.claude/wiki/`,讀取: +進入 `system-dev/wiki/`,讀取: - `INDEX.md`:目前已有哪些 wiki 頁面 - `status.md`:上次整理時間、進度 @@ -228,6 +228,6 @@ cards// - ❌ 修改任何 raw source 檔案 - ❌ 修改 `CLAUDE.md` - ❌ 動 `logseq/`、`.obsidian/`、`assets/` 資料夾 -- ❌ 刪除 `.claude/wiki/` 裡已有的頁面(只增補,不刪除) +- ❌ 刪除 `system-dev/wiki/` 裡已有的頁面(只增補,不刪除) - ❌ 把機敏資訊(密碼、金鑰、個資)寫進 wiki(遇到跳過並記錄) -- ❌ 整理沒有 `.claude/wiki/` 的資料夾(那不是這個 skill 的目標) +- ❌ 整理沒有 `system-dev/wiki/` 的資料夾(那不是這個 skill 的目標) diff --git a/scripts/install.sh b/scripts/install.sh index c66b0e5..071f227 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -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 < "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 # Cowork(claude.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 變動前必須有對應 SDD(docs/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 issue:CC 可直接 /issue-handle 讀回自己 repo 的 issue(禁自動輪詢)" \ " GitHub issues: CC can use /issue-handle to read issues from its own repo (no auto-polling)" diff --git a/scripts/update.sh b/scripts/update.sh index 4961c2b..210e8b6 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -30,11 +30,17 @@ UPDATED=() KEPT=() NEW=() TEMPLATED=() +MIGRATED=() # ── 版本比對:先看本機 vs 遠端,給使用者「值不值得更新」的判斷 ── +# VERSION 新位置在 system-dev/,舊位置在 .claude/(1.8.x 以前)。優先讀新、回退舊。 LOCAL_VER="$(tn '(未知)' '(unknown)')" -[ -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 '')" +if [ -f "system-dev/VERSION" ]; then + LOCAL_VER="$(tr -d '[:space:]' < system-dev/VERSION)" +elif [ -f ".claude/VERSION" ]; then + LOCAL_VER="$(tr -d '[:space:]' < .claude/VERSION)" +fi +REMOTE_VER="$(curl -sSL "$TEMPLATE_URL/system-dev/VERSION" 2>/dev/null | tr -d '[:space:]' || echo '')" echo "" echo "🔄 system-dev-template updater" @@ -58,6 +64,53 @@ if [ "$LOCAL_VER" = "$REMOTE_VER" ]; then echo "" fi +# ── 結構遷移(1.9.0):舊版把 wiki/VERSION 放 .claude/、工具 docs 放根 docs/ ── +# 新版一律收進 system-dev/。這裡冪等遷移:偵測舊位置 → 搬到 system-dev/,已搬過則略過。 +# 必須在「模組偵測」之前跑(偵測靠目錄存在與否判斷,搬完才看得到新位置)。 +# +# 安全原則: +# - wiki 整包搬(含 cards/ 與可能的 wiki/.git),用 mv 保留內含 .git。 +# - docs 只搬「工具自己鋪的白名單」子目錄;用戶自填在 docs/ 的其他內容一律不動。 +# - 目的地已存在同名 → 不覆蓋(保留用戶在新位置的東西),略過該項。 +migrate_dir() { # $1=舊路徑 $2=新路徑 + local from="$1" to="$2" + [ -e "$from" ] || return 0 # 舊的不存在 → 無需遷移 + if [ -e "$to" ]; then + return 0 # 新的已存在 → 冪等略過,不覆蓋 + fi + mkdir -p "$(dirname "$to")" + if mv "$from" "$to" 2>/dev/null; then + MIGRATED+=("$from → $to") + fi +} + +# 任一舊位置還在 → 需要遷移(遷移本身冪等:已搬的項目會被 migrate_dir 略過)。 +NEEDS_MIGRATE="no" +if [ -d ".claude/wiki" ] || [ -f ".claude/VERSION" ] \ + || [ -d "docs/3-specs" ] || [ -f "docs/SKILL.md" ] || [ -f "docs/README.md" ]; then + NEEDS_MIGRATE="yes" +fi + +if [ "$NEEDS_MIGRATE" = "yes" ]; then + t "🔧 偵測到舊版結構,遷移到 system-dev/ …" "🔧 Old layout detected — migrating into system-dev/ …" + mkdir -p system-dev + + # wiki(含 cards/ 與內含的 .git)整包搬 + migrate_dir ".claude/wiki" "system-dev/wiki" + # 工具版號 + migrate_dir ".claude/VERSION" "system-dev/VERSION" + # 工具文件白名單(只搬工具鋪的,用戶自填的 docs 內容不動) + migrate_dir "docs/SKILL.md" "system-dev/docs/SKILL.md" + migrate_dir "docs/README.md" "system-dev/docs/README.md" + migrate_dir "docs/1-vision" "system-dev/docs/1-vision" + migrate_dir "docs/2-architecture" "system-dev/docs/2-architecture" + migrate_dir "docs/3-specs" "system-dev/docs/3-specs" + migrate_dir "docs/4-guides" "system-dev/docs/4-guides" + migrate_dir "docs/5-records" "system-dev/docs/5-records" + migrate_dir "docs/6-user" "system-dev/docs/6-user" + echo "" +fi + # ── 工具函式 ─────────────────────────────────────── # 覆蓋更新:模板/邏輯檔,無條件抓最新版蓋掉。 update_file() { @@ -114,10 +167,11 @@ keep_with_template() { } # ── 偵測已安裝哪些模組(依現有檔案判斷,更新只動已裝的)── +# 遷移已在上面跑完,這裡看新位置 system-dev/。 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 +[ -d "system-dev/wiki" ] && HAS_WIKI=true +if [ -f ".claude/hooks/sdd-guard.sh" ] || [ -d "system-dev/docs/3-specs/TEMPLATE-sdd" ]; then HAS_SDD=true; fi t "📦 偵測到已安裝模組:" "📦 Detected installed modules:" $HAS_WIKI && echo " • LLM Wiki" @@ -136,11 +190,11 @@ keep_with_template ".claude/hooks/pre-write-guard.sh" "$TEMPLATE_URL/.claude/hoo # ── 模板/邏輯檔:覆蓋更新 ────────────────────────── # 共用 hook 與指引 update_file ".claude/commands/issue-handle.md" "$TEMPLATE_URL/.claude/commands/issue-handle.md" -update_file ".claude/VERSION" "$TEMPLATE_URL/.claude/VERSION" +update_file "system-dev/VERSION" "$TEMPLATE_URL/system-dev/VERSION" if $HAS_WIKI; then - # wiki 的「邏輯檔」:導航與 hooks,可覆蓋 - update_file ".claude/wiki/INDEX.md" "$TEMPLATE_URL/.claude/wiki/INDEX.md" + # wiki 的「邏輯檔」:導航與 hooks,可覆蓋。wiki 資料在 system-dev/,hooks/commands 留 .claude/。 + update_file "system-dev/wiki/INDEX.md" "$TEMPLATE_URL/system-dev/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" @@ -148,31 +202,31 @@ if $HAS_WIKI; then 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" # Cowork(claude.ai)的 wiki 整理 skill:規則檔,可覆蓋 - update_file "docs/SKILL.md" "$TEMPLATE_URL/docs/SKILL.md" + update_file "system-dev/docs/SKILL.md" "$TEMPLATE_URL/system-dev/docs/SKILL.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/TAXONOMY.md" - keep_file ".claude/wiki/.wikiignore" + keep_file "system-dev/wiki/status.md" + keep_file "system-dev/wiki/mistakes.md" + keep_file "system-dev/wiki/decisions-summary.md" + keep_file "system-dev/wiki/TAXONOMY.md" + keep_file "system-dev/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" + update_file "system-dev/docs/3-specs/TEMPLATE-sdd/design.md" "$TEMPLATE_URL/system-dev/docs/3-specs/TEMPLATE-sdd/design.md" + update_file "system-dev/docs/3-specs/TEMPLATE-sdd/tasks.md" "$TEMPLATE_URL/system-dev/docs/3-specs/TEMPLATE-sdd/tasks.md" + update_file "system-dev/docs/2-architecture/decisions/TEMPLATE-adr.md" "$TEMPLATE_URL/system-dev/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" +# ── 自我更新:把最新的 update.sh / install.sh 抓到 system-dev/scripts/ ── +# 這兩支在 main/scripts/ 下(不在 template/);落地位置新版收進 system-dev/scripts/。 +update_file "system-dev/scripts/update.sh" "$REPO_RAW/scripts/update.sh" +update_file "system-dev/scripts/install.sh" "$REPO_RAW/scripts/install.sh" -chmod +x .claude/hooks/*.sh scripts/*.sh 2>/dev/null || true +chmod +x .claude/hooks/*.sh system-dev/scripts/*.sh 2>/dev/null || true # ── 使用者資料檔:絕不碰,但提醒「設定可能有新欄位要手動補」── keep_file ".claude/settings.json" @@ -181,6 +235,11 @@ keep_file "CLAUDE.md" # ── 結果輸出 ─────────────────────────────────────── echo "" echo "─────────────────────────────────" +if [ ${#MIGRATED[@]} -gt 0 ]; then + echo "" + t "📦 結構遷移(已收進 system-dev/):" "📦 Layout migrated (moved into system-dev/):" + for f in "${MIGRATED[@]}"; do echo " ⇒ $f"; done +fi if [ ${#NEW[@]} -gt 0 ]; then echo "" t "🆕 新功能(舊版沒有,已加入):" "🆕 New features (absent in the old version, now added):" @@ -229,6 +288,6 @@ fi echo "" t "🚀 更新完成:${LOCAL_VER} → ${REMOTE_VER}" "🚀 Update complete: ${LOCAL_VER} → ${REMOTE_VER}" -t " 下次更新直接跑:bash scripts/update.sh" " Next time, just run: bash scripts/update.sh" +t " 下次更新直接跑:bash system-dev/scripts/update.sh" " Next time, just run: bash system-dev/scripts/update.sh" t " 改了什麼看:CHANGELOG.md" " See what changed: CHANGELOG.md" echo "" diff --git a/template/.claude/VERSION b/template/.claude/VERSION deleted file mode 100644 index 0bfbd57..0000000 --- a/template/.claude/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.8.2 \ No newline at end of file diff --git a/template/.claude/commands/sdd-check.md b/template/.claude/commands/sdd-check.md index 54c97d2..fb4bfde 100644 --- a/template/.claude/commands/sdd-check.md +++ b/template/.claude/commands/sdd-check.md @@ -15,7 +15,7 @@ ### 第二步:尋找對應 SDD -在 `docs/3-specs/` 下尋找對應的子系統目錄,確認有沒有: +在 `system-dev/docs/3-specs/` 下尋找對應的子系統目錄,確認有沒有: - `design.md`(設計文件) - `tasks.md`(任務清單) @@ -23,7 +23,7 @@ **情況 A:找到對應 SDD** ``` -✅ 找到 SDD:docs/3-specs/[子系統]/ +✅ 找到 SDD:system-dev/docs/3-specs/[子系統]/ 📋 design.md:[確認] 📋 tasks.md:[確認,列出相關 task] 🎯 對應 task:[編號和描述] @@ -34,7 +34,7 @@ ``` ⚠️ 找不到對應 SDD 任務:[描述] -建議在 docs/3-specs/[建議子系統名]/ 建立 SDD +建議在 system-dev/docs/3-specs/[建議子系統名]/ 建立 SDD 要我幫你起草 design.md 嗎?(需要你確認後才動手) ``` diff --git a/template/.claude/commands/wiki-capture.md b/template/.claude/commands/wiki-capture.md index fecb6d7..d10e13b 100644 --- a/template/.claude/commands/wiki-capture.md +++ b/template/.claude/commands/wiki-capture.md @@ -11,9 +11,9 @@ 把任何內容寫進 wiki 前,先確認**不含**密碼 / API 金鑰 / 私鑰 / 連線字串帳密 / 個資(身分證、信用卡)。 - 命中 → 不要記「值」,改記「位置」(例:「DB 密碼放 `.env`,不入 wiki」) -- 來源整檔機敏 → 提醒使用者加進 `.claude/wiki/.wikiignore` +- 來源整檔機敏 → 提醒使用者加進 `system-dev/wiki/.wikiignore` - 真要保留示範格式 → 該行尾加 `wiki-secret-ok` 標記 -> 這是協議層自律。最後一道 `wiki-secret-scan.sh` hook 會在寫入 `.claude/wiki/` 時機械攔截,但別依賴它兜底——當場就不要把機敏值帶進來。 +> 這是協議層自律。最後一道 `wiki-secret-scan.sh` hook 會在寫入 `system-dev/wiki/` 時機械攔截,但別依賴它兜底——當場就不要把機敏值帶進來。 ### 第一步:辨識對話中的可記錄內容 @@ -21,7 +21,7 @@ | 類型 | 判斷標準 | 存到哪 | |------|---------|-------| -| 架構決策 | 「為什麼選A不選B」「我們決定用X」 | `decisions-summary.md` + `docs/2-architecture/decisions/` | +| 架構決策 | 「為什麼選A不選B」「我們決定用X」 | `decisions-summary.md` + `system-dev/docs/2-architecture/decisions/` | | CC 的誤解被糾正 | CC 說了某件事,使用者說「不是,是...」 | `mistakes.md` | | 重要狀態更新 | 完成了某件事、阻擋了某件事 | `status.md` | | 技術發現 | 踩到坑、找到解法、重要行為確認 | `mistakes.md` 或對應 SDD | @@ -59,10 +59,10 @@ ## [主題] — [YYYY-MM-DD] **結論**:[一句話] **原因**:[簡短說明] -**詳細**:docs/2-architecture/decisions/[檔名] +**詳細**:system-dev/docs/2-architecture/decisions/[檔名] ``` -重大決策同時在 `docs/2-architecture/decisions/` 建立 ADR 檔案。 +重大決策同時在 `system-dev/docs/2-architecture/decisions/` 建立 ADR 檔案。 ### 第四步:確認 diff --git a/template/.claude/commands/wiki-init.md b/template/.claude/commands/wiki-init.md index cbf33ff..c57c396 100644 --- a/template/.claude/commands/wiki-init.md +++ b/template/.claude/commands/wiki-init.md @@ -19,7 +19,7 @@ 唯一例外:原文是**不可改動的正式文件**(簽署過的規格、法規、合約),必須逐字讀原文——這種才在 wiki 裡用指針指回去,並註明「逐字依原文」。除此之外,一律改寫。 -**raw source 永遠唯讀**:所有產出只往 `.claude/wiki/` 寫,絕不改動、搬移、重新命名原文。 +**raw source 永遠唯讀**:所有產出只往 `system-dev/wiki/` 寫,絕不改動、搬移、重新命名原文。 --- @@ -28,7 +28,7 @@ ### 第一步:偵測專案狀態 檢查以下項目,判斷是新專案還是已有專案: -- 根目錄有沒有 `.claude/wiki/` +- 根目錄有沒有 `system-dev/wiki/` - 根目錄有沒有 `docs/`(或 vault 的 `pages/`、`journals/`、根目錄 `.md`) - 有沒有散落的 `.md` 檔案 @@ -43,7 +43,7 @@ ### 第二步:已有專案的掃描(已有專案才執行) 1. 遞迴找出 raw source 裡所有 `.md` 檔案 -2. **先套用 `.claude/wiki/.wikiignore`**:命中 pattern 的檔案整個排除,不讀不編入。 +2. **先套用 `system-dev/wiki/.wikiignore`**:命中 pattern 的檔案整個排除,不讀不編入。 - 若 `.wikiignore` 不存在,從範本建立一份(預設排除 `.env`/`*.pem`/`*secret*` 等) - 被排除的檔案在清單裡標「🚫 .wikiignore 排除」,**不可被覆蓋** 3. 對其餘檔案標注**改寫計畫**:會萃取成哪些 wiki 條目。一份原文可能拆成多個概念原子條目,多份相關原文也可能合併成一條。 @@ -66,7 +66,7 @@ wiki 採**三層 + 標籤橫切**架構(183 卡實證,issue #8): ``` -.claude/wiki/ +system-dev/wiki/ ├── INDEX.md ← 頂層:標籤視圖(不是資料夾列表) ├── TAXONOMY.md ← 標籤字典(分類骨架,受控擴充:先查重再登記) ├── status.md / mistakes.md / decisions-summary.md @@ -80,16 +80,16 @@ wiki 採**三層 + 標籤橫切**架構(183 卡實證,issue #8): > **桶子索引固定叫 `00-INDEX.md`**(issue #6):`00-` 前綴讓它排序最前、一眼可辨(像 README 之於資料夾),AI 載入任何 `cards//` 一律先讀它,不必猜。檔內 H1 仍寫主題名(如 `# PKM 知識管理`),語意不丟。 -一般專案仍可同時建 `docs/` 分類樹(SDD 等): +一般專案仍可同時建 `system-dev/docs/` 分類樹(SDD 等): ``` -docs/{1-vision,2-architecture/decisions,3-specs,4-guides,5-records/{incidents,test-reports},6-user} +system-dev/docs/{1-vision,2-architecture/decisions,3-specs,4-guides,5-records/{incidents,test-reports},6-user} ``` -(純 PKM vault 不需要 `docs/` 分類樹時,只建 `.claude/wiki/`。) +(純 PKM vault 不需要 `system-dev/docs/` 分類樹時,只建 `system-dev/wiki/`。) 檔案(不存在才建): -- `.claude/wiki/INDEX.md`、`TAXONOMY.md` -- `.claude/wiki/status.md`、`mistakes.md`、`decisions-summary.md` -- `docs/README.md`(一般專案才需要) +- `system-dev/wiki/INDEX.md`、`TAXONOMY.md` +- `system-dev/wiki/status.md`、`mistakes.md`、`decisions-summary.md` +- `system-dev/docs/README.md`(一般專案才需要) ### 第四步:訪談(每次一個問題) @@ -168,7 +168,7 @@ gloss: 一句話定義這個概念是什麼(給下游語義 normalize 用, **INDEX.md 是標籤視圖**(非資料夾列表),`00-INDEX.md` 是桶內容器(只連不重寫,H2/H3 分節)。 頂層索引指桶子索引帶路徑:`[[pkm/00-INDEX]]`。 -> 與 claude.ai Cowork 的 `docs/SKILL.md` 改寫邏輯一致,兩條路徑(CC / Cowork)產出同一種 wiki。 +> 與 claude.ai Cowork 的 `system-dev/docs/SKILL.md` 改寫邏輯一致,兩條路徑(CC / Cowork)產出同一種 wiki。 ### 第六步:完成報告 + 驗證 diff --git a/template/.claude/commands/wiki-recall.md b/template/.claude/commands/wiki-recall.md index e6055c5..2159a5e 100644 --- a/template/.claude/commands/wiki-recall.md +++ b/template/.claude/commands/wiki-recall.md @@ -17,18 +17,18 @@ init(建) → update(存,session 末) ↔ **recall(接,session 初)** → ca ### 第一步:讀 status.md(當前進度) -讀 `.claude/wiki/status.md`,掌握: +讀 `system-dev/wiki/status.md`,掌握: - 正在做什麼、阻擋點 - 下次 session 第一件事 - 待負責人確認、已知問題 ### 第二步:讀 decisions-summary.md(為什麼這樣做) -讀 `.claude/wiki/decisions-summary.md`,掌握相關的架構決策——避免重新討論已定案的事。 +讀 `system-dev/wiki/decisions-summary.md`,掌握相關的架構決策——避免重新討論已定案的事。 ### 第三步:讀 mistakes.md(別重犯) -讀 `.claude/wiki/mistakes.md`,掌握已知誤解 + 快速檢查清單。 +讀 `system-dev/wiki/mistakes.md`,掌握已知誤解 + 快速檢查清單。 ### 第四步:掃 wishlist / HANDOFF(如果有) diff --git a/template/.claude/hooks/sdd-guard.sh b/template/.claude/hooks/sdd-guard.sh index f249147..2295cd2 100755 --- a/template/.claude/hooks/sdd-guard.sh +++ b/template/.claude/hooks/sdd-guard.sh @@ -4,7 +4,7 @@ # # 掛在 settings.json 的 PreToolUse(matcher: Write|Edit)。 # stdin 收到 JSON:{ tool_name, tool_input: { file_path, ... } } -# 行為:動到 code 檔(.ts/.go/...)但 docs/3-specs/ 下沒有任何 SDD → 警告(exit 2 擋)。 +# 行為:動到 code 檔(.ts/.go/...)但 system-dev/docs/3-specs/ 下沒有任何 SDD → 警告(exit 2 擋)。 # # 誠實限制(抄 arcrun):只擋語法層明顯違規(直接寫 code 檔)。 # 藏在 helper 裡、用 bash 繞道的改動擋不到。 @@ -32,25 +32,25 @@ esac # 改 SDD 自己 / 測試檔 → 放行 case "$FILE_PATH" in - *docs/3-specs/*) exit 0 ;; + *system-dev/docs/3-specs/*) exit 0 ;; *_test.*|*.test.*|*.spec.*|*/tests/*|*/test/*) exit 0 ;; esac -# docs/3-specs/ 下完全沒有 design.md → 攔 +# system-dev/docs/3-specs/ 下完全沒有 design.md → 攔 SDD_COUNT=0 -if [ -d "docs/3-specs" ]; then - SDD_COUNT=$(find docs/3-specs -name 'design.md' -not -path '*TEMPLATE*' 2>/dev/null | wc -l | tr -d ' ') +if [ -d "system-dev/docs/3-specs" ]; then + SDD_COUNT=$(find system-dev/docs/3-specs -name 'design.md' -not -path '*TEMPLATE*' 2>/dev/null | wc -l | tr -d ' ') fi if [ "$SDD_COUNT" -eq 0 ]; then cat >&2 <&2 +echo "📋 提醒:system-dev/docs/3-specs/ 下有 SDD。動手前請確認已讀對應 design.md 並在回覆宣告。" >&2 exit 0 diff --git a/template/.claude/hooks/session-start-recall.sh b/template/.claude/hooks/session-start-recall.sh index 8038758..55a355a 100755 --- a/template/.claude/hooks/session-start-recall.sh +++ b/template/.claude/hooks/session-start-recall.sh @@ -10,7 +10,19 @@ set -euo pipefail -STATUS_FILE=".claude/wiki/status.md" +STATUS_FILE="system-dev/wiki/status.md" + +# ── 舊結構防呆(1.9.0 遷移第 2 層保險)── +# 新版 wiki 收進 system-dev/。若偵測到舊位置 .claude/wiki/ 還在、但新位置沒 status, +# 代表使用者升級了規則卻沒跑遷移(low-code 使用者常見)→ 出聲提示,讓 CC 當場可代為遷移, +# 不要默默用不到新結構而出錯。 +if [ -d ".claude/wiki" ] && [ ! -f "$STATUS_FILE" ]; then + echo "⚠️ 偵測到舊版 wiki 結構(.claude/wiki/),尚未遷移到 system-dev/wiki/。" + echo " 請跑:bash system-dev/scripts/update.sh" + echo " 或直接叫我(CC):「幫我把 wiki 遷移到 system-dev/」——我可以代為搬移。" + echo " (未遷移時接關與 /wiki-init 會找錯位置。)" + exit 0 +fi # 沒有 wiki 就安靜退出(exit 0),不干擾還沒 /wiki-init 的專案 if [ ! -f "$STATUS_FILE" ]; then diff --git a/template/.claude/hooks/wiki-secret-scan.sh b/template/.claude/hooks/wiki-secret-scan.sh index d0600f8..91355f0 100755 --- a/template/.claude/hooks/wiki-secret-scan.sh +++ b/template/.claude/hooks/wiki-secret-scan.sh @@ -3,11 +3,11 @@ # # 為什麼存在:wiki 的 ignore 規則(.wikiignore + 行內標記)是「協議層」,靠 CC 遵守。 # 但密碼/金鑰/個資外洩是「不可逆」後果——只靠口頭約束太危險。 -# 這支 hook 是機械式底線:CC 真的把機敏資訊寫進 .claude/wiki/ 的那一刻 → exit 2 擋下。 +# 這支 hook 是機械式底線:CC 真的把機敏資訊寫進 system-dev/wiki/ 的那一刻 → exit 2 擋下。 # # 掛在 settings.json 的 PreToolUse(matcher: Write|Edit)。 # stdin 收到 JSON:{ tool_name, tool_input: { file_path, content?, new_string? } } -# 行為:只在目標路徑是 .claude/wiki/** 時啟動,掃要寫入的內容,命中機敏特徵 → exit 2。 +# 行為:只在目標路徑是 system-dev/wiki/** 時啟動,掃要寫入的內容,命中機敏特徵 → exit 2。 # # 誠實限制(抄 sdd-guard):regex 偵測有偽陰/偽陽。 # 擋的是「明顯特徵的機敏字串被自動抄進 wiki」,擋不了刻意混淆/編碼的繞道。 @@ -33,7 +33,7 @@ fi # 只管寫進 wiki 的動作。其他路徑放行(這支專責 wiki 洩漏,不是全域 secret scanner) case "$FILE_PATH" in - *.claude/wiki/*) ;; + *system-dev/wiki/*) ;; *) exit 0 ;; esac @@ -102,7 +102,7 @@ wiki 是會被 CC 反覆讀取、可能進版控的記憶空間。 請改成下列任一做法: 1. 不要把機敏值寫進 wiki,改記「位置」(例:「DB 密碼放 1Password / .env,不入 wiki」) 2. 確定是誤判(例:在示範格式)→ 該行尾加註記 wiki-secret-ok 後重寫 - 3. 整個來源檔本就機敏 → 加進 .claude/wiki/.wikiignore,別讓它被編入 + 3. 整個來源檔本就機敏 → 加進 system-dev/wiki/.wikiignore,別讓它被編入 誠實限制:本掃描靠特徵比對,有偽陽/偽陰,是「意外外洩的機械底線」而非保險箱。 真正的密鑰本就不該進版控。 diff --git a/template/CLAUDE.md b/template/CLAUDE.md index e03564d..87ae11c 100644 --- a/template/CLAUDE.md +++ b/template/CLAUDE.md @@ -7,7 +7,7 @@ ## 絕對鐵律(違反 = 停手) -1. **任何 code 變動前必須有對應 SDD**(`docs/3-specs/[子系統]/design.md`) +1. **任何 code 變動前必須有對應 SDD**(`system-dev/docs/3-specs/[子系統]/design.md`) 2. [技術棧限制,例如:前端只用 React,不引入其他框架] 3. [其他專案特定限制] @@ -19,15 +19,15 @@ 開始任一任務,按順序: -1. 讀 `.claude/wiki/status.md`(3 分鐘,了解當前狀態) -2. 確認有對應 SDD(`docs/3-specs/`) +1. 讀 `system-dev/wiki/status.md`(3 分鐘,了解當前狀態) +2. 確認有對應 SDD(`system-dev/docs/3-specs/`) 3. 在回覆開頭宣告: ``` 📋 已讀 SDD:<路徑> 🎯 對應 task:<編號> 🚧 執行範圍:<會動哪些檔案> ``` -4. 完成後更新 `.claude/wiki/status.md` +4. 完成後更新 `system-dev/wiki/status.md` --- @@ -35,9 +35,9 @@ | 檔案 | 時機 | 用途 | |------|------|------| -| `.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` | 遇到設計判斷時 | 架構決策快速查 | > 開 session 由 `SessionStart` hook 自動注入 status 重點。沒自動接關 → 打 `/wiki-recall`。 > status/wiki 是 **快照非即時狀態**:讀快照 **+ 核實快照**,不盲信。 @@ -52,7 +52,7 @@ | 由誰整理 | 規則檔(採集當下必讀) | |----------|------------------------| | **Claude Code(CC)** | `/wiki-init`(初始化/採集)、`/wiki-capture`(存結論),規則寫在指令內文 | -| **Claude.ai(Cowork)** | `docs/SKILL.md`(skill `wiki-cowork-scan`),與 CC 共用同一套規則 | +| **Claude.ai(Cowork)** | `system-dev/docs/SKILL.md`(skill `wiki-cowork-scan`),與 CC 共用同一套規則 | 兩條路徑**輸出格式相同、規則一致**:gloss、typed-edge、標籤的寫法在兩份裡都有,任一方整理過另一方不覆蓋。 @@ -62,9 +62,9 @@ | 檔案 | 內容 | |------|------| -| `docs/README.md` | 文件分類規則 | -| `docs/3-specs/` | 所有 SDD | -| `docs/2-architecture/decisions/` | 架構決策記錄 | +| `system-dev/docs/README.md` | 文件分類規則 | +| `system-dev/docs/3-specs/` | 所有 SDD | +| `system-dev/docs/2-architecture/decisions/` | 架構決策記錄 | --- @@ -72,8 +72,8 @@ | 類別 | 位置 | |------|------| -| 架構決策 | `docs/2-architecture/decisions/` | -| SDD | `docs/3-specs/[子系統]/` | -| 操作手冊 | `docs/4-guides/` | -| 事件記錄 | `docs/5-records/incidents/` | -| 測試報告 | `docs/5-records/test-reports/` | +| 架構決策 | `system-dev/docs/2-architecture/decisions/` | +| SDD | `system-dev/docs/3-specs/[子系統]/` | +| 操作手冊 | `system-dev/docs/4-guides/` | +| 事件記錄 | `system-dev/docs/5-records/incidents/` | +| 測試報告 | `system-dev/docs/5-records/test-reports/` | diff --git a/template/system-dev/VERSION b/template/system-dev/VERSION new file mode 100644 index 0000000..abb1658 --- /dev/null +++ b/template/system-dev/VERSION @@ -0,0 +1 @@ +1.9.0 \ No newline at end of file diff --git a/template/docs/2-architecture/decisions/TEMPLATE-adr.md b/template/system-dev/docs/2-architecture/decisions/TEMPLATE-adr.md similarity index 100% rename from template/docs/2-architecture/decisions/TEMPLATE-adr.md rename to template/system-dev/docs/2-architecture/decisions/TEMPLATE-adr.md diff --git a/template/docs/3-specs/TEMPLATE-sdd/design.md b/template/system-dev/docs/3-specs/TEMPLATE-sdd/design.md similarity index 100% rename from template/docs/3-specs/TEMPLATE-sdd/design.md rename to template/system-dev/docs/3-specs/TEMPLATE-sdd/design.md diff --git a/template/docs/3-specs/TEMPLATE-sdd/tasks.md b/template/system-dev/docs/3-specs/TEMPLATE-sdd/tasks.md similarity index 100% rename from template/docs/3-specs/TEMPLATE-sdd/tasks.md rename to template/system-dev/docs/3-specs/TEMPLATE-sdd/tasks.md diff --git a/template/docs/README.md b/template/system-dev/docs/README.md similarity index 100% rename from template/docs/README.md rename to template/system-dev/docs/README.md diff --git a/template/docs/SKILL.md b/template/system-dev/docs/SKILL.md similarity index 94% rename from template/docs/SKILL.md rename to template/system-dev/docs/SKILL.md index 647f78b..8977433 100644 --- a/template/docs/SKILL.md +++ b/template/system-dev/docs/SKILL.md @@ -12,7 +12,7 @@ description: "掃描本機 Documents 下所有裝了 system-dev-template 的資 | 層 | 規則 | |------------|-------------------------------------------| | raw source | 只讀,不動 | -| `.claude/wiki/` | 唯一輸出地點,只增不覆 | +| `system-dev/wiki/` | 唯一輸出地點,只增不覆 | | `CLAUDE.md` | 不動 | | `logseq/`、`.obsidian/`、`assets/` | 絕對不動 | @@ -22,12 +22,12 @@ description: "掃描本機 Documents 下所有裝了 system-dev-template 的資 ## 第一步:發現所有目標資料夾 -掃描 `~/Documents`(遞迴深度 3 層),找出所有含 `.claude/wiki/` 的資料夾。 +掃描 `~/Documents`(遞迴深度 3 層),找出所有含 `system-dev/wiki/` 的資料夾。 ``` ~/Documents/ - project-a/.claude/wiki/ ← ✅ 目標 - Logseq/.claude/wiki/ ← ✅ 目標 + project-a/system-dev/wiki/ ← ✅ 目標 + Logseq/system-dev/wiki/ ← ✅ 目標 其他資料夾/ ← ❌ 跳過 ``` @@ -37,7 +37,7 @@ description: "掃描本機 Documents 下所有裝了 system-dev-template 的資 ## 第二步:對每個資料夾偵測 vault 類型 -進入每個目標資料夾的**根目錄**(`.claude/wiki/` 的上兩層),依序判斷: +進入每個目標資料夾的**根目錄**(`system-dev/wiki/` 的上兩層),依序判斷: ### 判斷順序(與 install.sh 一致) @@ -60,7 +60,7 @@ else ## 第三步:讀取現有 wiki 狀態 -進入 `.claude/wiki/`,讀取: +進入 `system-dev/wiki/`,讀取: - `INDEX.md`:目前已有哪些 wiki 頁面 - `status.md`:上次整理時間、進度 @@ -228,6 +228,6 @@ cards// - ❌ 修改任何 raw source 檔案 - ❌ 修改 `CLAUDE.md` - ❌ 動 `logseq/`、`.obsidian/`、`assets/` 資料夾 -- ❌ 刪除 `.claude/wiki/` 裡已有的頁面(只增補,不刪除) +- ❌ 刪除 `system-dev/wiki/` 裡已有的頁面(只增補,不刪除) - ❌ 把機敏資訊(密碼、金鑰、個資)寫進 wiki(遇到跳過並記錄) -- ❌ 整理沒有 `.claude/wiki/` 的資料夾(那不是這個 skill 的目標) +- ❌ 整理沒有 `system-dev/wiki/` 的資料夾(那不是這個 skill 的目標) diff --git a/template/.claude/wiki/.wikiignore b/template/system-dev/wiki/.wikiignore similarity index 100% rename from template/.claude/wiki/.wikiignore rename to template/system-dev/wiki/.wikiignore diff --git a/template/.claude/wiki/INDEX.md b/template/system-dev/wiki/INDEX.md similarity index 94% rename from template/.claude/wiki/INDEX.md rename to template/system-dev/wiki/INDEX.md index 0d3e89d..c87230c 100644 --- a/template/.claude/wiki/INDEX.md +++ b/template/system-dev/wiki/INDEX.md @@ -1,4 +1,4 @@ -# .claude/wiki/ — LLM 記憶系統 +# system-dev/wiki/ — LLM 記憶系統 > 新 session 開始時從這裡導航。 > 目的:讓 CC 不需要重新學習已知的事。 @@ -21,7 +21,7 @@ 1. 只增不刪——記錄 append,決策改了加新條目說明「舊決策已更新」 2. status.md 每次 session 結束更新 3. mistakes.md 每次被糾正後 append -4. 發現新的重要決策 → 同時更新 decisions-summary.md 和 docs/2-architecture/decisions/ +4. 發現新的重要決策 → 同時更新 decisions-summary.md 和 system-dev/docs/2-architecture/decisions/ --- diff --git a/template/.claude/wiki/TAXONOMY.md b/template/system-dev/wiki/TAXONOMY.md similarity index 100% rename from template/.claude/wiki/TAXONOMY.md rename to template/system-dev/wiki/TAXONOMY.md diff --git a/template/.claude/wiki/decisions-summary.md b/template/system-dev/wiki/decisions-summary.md similarity index 61% rename from template/.claude/wiki/decisions-summary.md rename to template/system-dev/wiki/decisions-summary.md index e539e3d..4bc5570 100644 --- a/template/.claude/wiki/decisions-summary.md +++ b/template/system-dev/wiki/decisions-summary.md @@ -1,7 +1,7 @@ # 架構決策摘要 > 遇到設計判斷時查這裡。 -> 完整脈絡在 docs/2-architecture/decisions/。 +> 完整脈絡在 system-dev/docs/2-architecture/decisions/。 --- @@ -11,4 +11,4 @@ ## [主題] — [YYYY-MM-DD] **結論**:[一句話] **原因**:[簡短說明] -**詳細**:docs/2-architecture/decisions/[對應檔案] +**詳細**:system-dev/docs/2-architecture/decisions/[對應檔案] diff --git a/template/.claude/wiki/mistakes.md b/template/system-dev/wiki/mistakes.md similarity index 100% rename from template/.claude/wiki/mistakes.md rename to template/system-dev/wiki/mistakes.md diff --git a/template/.claude/wiki/status.md b/template/system-dev/wiki/status.md similarity index 100% rename from template/.claude/wiki/status.md rename to template/system-dev/wiki/status.md