chore: template 1.16.0——wiki 讀取兩支 hook(查詢即搜尋 wiki+subagent 自動注入)

leo 2026-07-20:「花很多力氣去產生 wiki,最重要的就是要可以查詢,
結果要查的時候就跳過,那就白寫了」

- wiki-first-search.sh(Grep|Glob|Read):查 code 的當下用同組關鍵字 grep wiki,只推命中行
- subagent-wiki-guard.sh(Task):查證類任務自動注入「先查 wiki」給 subagent
- update.sh/install.sh 來源改指 Gitea(原指 GitHub uncle6me-web 已 suspend=自動更新早就死了)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-21 01:40:55 +08:00
parent 20c7610371
commit df1b953d1f
11 changed files with 521 additions and 20 deletions
+1 -1
View File
@@ -1 +1 @@
1.12.0
1.16.0
@@ -1,6 +1,10 @@
---
status: draft # active | draft | paused | closed(生命週期鐵律見 ../SDD-LIFECYCLE.md
superseded_by: "" # closed 且被取代時填接替的 SDD 資料夾名
---
# [子系統名稱] — Design
> 狀態:[草稿 / 審核中 / 已採納 / 已廢棄]
> 建立:[YYYY-MM-DD] | 最後更新:[YYYY-MM-DD]
> 負責人:[名稱]
@@ -0,0 +1,81 @@
# Logseq 任務 marker 解析(單一真相源)
> **這是「Logseq 原生任務語法」解析的唯一權威規格。** 任何要從 Logseq graph
> 抓任務狀態的功能,一律 import 這份、不得各寫一份自己的 mapping。
>
> **已知兩個消費者**(共用同一套解析,見各自 issue):
> 1. **vault 萃取**`/wiki-extract`template#5):marker → 卡片 frontmatter `task_status`。
> 2. **tasks→Project 投影**`system-dev/workflows/tasks-project-sync.*`template#4):
> 當投影來源是 Logseq graphnotes/kb)時,用這份判斷任務與狀態。
>
> 兩者**只共用「怎麼 parse」**(哪幾行是任務、marker 是什麼、正規狀態是什麼、跳過什麼);
> parse 完各自要「拿狀態做什麼」(寫卡 vs 投影 issue)不同,那部分各管各的。
---
## 為什麼不是 GFM checkbox(規格更正,leo 2026-07-04 發現)
Logseq 的原生任務**不是** GFM 的 `- [ ]` / `- [x]`,而是**大寫 marker 開頭的 block**
```
- TODO AI 查看 leo21c 內所有 Repo,找到本地 Repo 搬到 Gitea
- DOING 建立知識總庫,可查所有子庫
- DONE 手機和電腦 Logseq 可以被放進知識總庫
```
若照舊規格只抓 `- [ ]` checkbox**notes / kb 兩個 Logseq graph 的任務會全數漏抓**。
> 兩種源、兩套語法、同一條下游管線:
> - **SDD `tasks.md`**(各 repo `system-dev/docs/3-specs/**`)→ GFM checkbox(現行不變)。
> - **Logseq graphnotes / kb** → 本檔的大寫 marker。
---
## 解析規格
### 1. 任務行辨識(regex
```
^\s*- (TODO|DOING|NOW|LATER|WAITING|DONE|CANCELED|CANCELLED)\s+
```
- marker 必須是 block`-` bullet)的**開頭第一個 token**、全大寫、後接空白。
- `CANCELED` 與英式 `CANCELLED` 皆收(Logseq 兩種都產)。
- marker 後面到行尾(或到子 bullet 之前)是**任務內文**。
### 2. marker → 正規狀態(task_status
| Logseq marker | 正規 task_status |
|---------------|------------------|
| `TODO``LATER` | `todo` |
| `DOING``NOW` | `in-progress` |
| `WAITING` | `blocked` |
| `DONE` | `done` |
| `CANCELED``CANCELLED` | `closed` |
> `LATER`/`NOW` 是 Logseq「排程視圖」用的同義 markerLATER≈TODO、NOW≈DOING),
> 正規化後與 TODO/DOING 併軌,下游不必區分。
### 3. 必須跳過的東西(別當任務內文)
Logseq 的任務 block 底下常掛時間戳與屬性行,這些**不是內文**,解析時整段略過:
- **`:LOGBOOK:``:END:` 區塊**:marker 被點擊計時產生的時間戳紀錄。
遇到 `:LOGBOOK:` 那行起、到 `:END:` 那行止(含兩端),整塊丟掉。
- **屬性行 `key:: value`**:如 `collapsed:: true``id:: 65a...``SCHEDULED:: <...>`
`DEADLINE:: <...>`。凡符合 `^\s*[\w-]+:: ` 的行都是屬性,不是內文。
`SCHEDULED`/`DEADLINE` 的日期若下游要用可另抓,但**不得當任務描述文字**。)
### 4. 巢狀子 bullet
任務 block 底下縮排的子 bullet 是該任務的補充說明(非獨立任務,除非子 bullet 自己也帶 marker)。
萃取時可併入該任務的描述脈絡;投影時只取母 block 那行當任務標題。
---
## 自檢(實作或 LLM 執行前跑一遍)
- [ ] 用的是大寫 marker regex**不是** `- [ ]` checkbox。
- [ ] 八個 marker 全部覆蓋(含 `LATER`/`NOW`/`CANCELLED` 別漏)。
- [ ] `:LOGBOOK:...:END:``key:: value` 屬性行有跳過,沒混進任務文字。
- [ ] 狀態用上表**正規名**`todo`/`in-progress`/`blocked`/`done`/`closed`),不是原始 marker 字面。
+36 -3
View File
@@ -26,9 +26,9 @@ t() { if [ "$IS_ZH" = "yes" ]; then printf '%s\n' "$1"; else printf '%s\n' "$2";
# tn = 不換行版(給 prompt 用)
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"
REPO_URL="https://git.uncle6.me/Leo/system-dev-template/raw/branch/main/template"
# install.sh / update.sh 住在 main/scripts/(不在 template/)。
SCRIPTS_URL="https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main/scripts"
SCRIPTS_URL="https://git.uncle6.me/Leo/system-dev-template/raw/branch/main/scripts"
CREATED=()
SKIPPED=()
@@ -115,7 +115,7 @@ if [ -d "system-dev" ] || [ -d ".claude/wiki" ] || [ -f ".claude/VERSION" ]; the
t " 後續的更新、遷移、補新檔,一律由「更新腳本」處理(不要重跑 install):" \
" All updates, migrations, and new-file additions are handled by the UPDATER (don't re-run install):"
echo ""
echo " curl -sSL https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main/scripts/update.sh | bash"
echo " curl -sSL https://git.uncle6.me/Leo/system-dev-template/raw/branch/main/scripts/update.sh | bash"
echo ""
t " (重跑 install 可能建出空白範本、跟你的真資料並存,故在此停止。)" \
" (Re-running install could create empty templates alongside your real data, so it stops here.)"
@@ -254,6 +254,10 @@ create_dir ".claude/commands"
create_dir ".claude/hooks"
download_if_missing "system-dev/docs/README.md" "$REPO_URL/system-dev/docs/README.md"
# Logseq 任務 marker 解析(單一真相源):vault 萃取(/wiki-extract)與 tasks→Project
# 投影(tasks-project-sync)共用同一套解析,別各寫一份。放共用區,兩模組都拿得到。
download_if_missing "system-dev/docs/4-guides/logseq-markers.md" "$REPO_URL/system-dev/docs/4-guides/logseq-markers.md"
# 工具版號:放 system-dev/,不寄生 .claude/。
download_if_missing "system-dev/VERSION" "$REPO_URL/system-dev/VERSION"
@@ -277,6 +281,8 @@ if $WANT_WIKI; then
download_if_missing ".claude/commands/wiki-capture.md" "$REPO_URL/.claude/commands/wiki-capture.md"
download_if_missing ".claude/commands/wiki-update.md" "$REPO_URL/.claude/commands/wiki-update.md"
download_if_missing ".claude/commands/wiki-recall.md" "$REPO_URL/.claude/commands/wiki-recall.md"
# vault 增量萃取(Logseq/Obsidian → system-dev/wiki,冪等):給 Routine 反覆跑。
download_if_missing ".claude/commands/wiki-extract.md" "$REPO_URL/.claude/commands/wiki-extract.md"
# wiki 相關 hooks:接關 + 機敏掃描
download_if_missing ".claude/hooks/session-start-recall.sh" "$REPO_URL/.claude/hooks/session-start-recall.sh"
@@ -296,6 +302,18 @@ if $WANT_SDD; then
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"
# SDD 生命週期鐵律(1.14,issue #6):規則真相源 + 規格變更緩衝區 + 獨立單一活性檢查
download_if_missing "system-dev/docs/3-specs/SDD-LIFECYCLE.md" "$REPO_URL/system-dev/docs/3-specs/SDD-LIFECYCLE.md"
download_if_missing "system-dev/docs/3-specs/pending-changes.md" "$REPO_URL/system-dev/docs/3-specs/pending-changes.md"
download_if_missing "system-dev/scripts/sdd-active-check.sh" "$REPO_URL/scripts/sdd-active-check.sh"
# ── tasks⇄Project 投影(optionalissue #16)──────────────────
# 帶檔 ≠ 啟用:workflow yaml 只是「留記錄+手動啟用素材」,啟用=對話答好且 acr push。
# 投影邏輯依附 tasks.md(住 3-specs),故隨 SDD 模組帶下來;裝了不代表開。
create_dir "system-dev/workflows"
download_if_missing "system-dev/workflows/tasks-project-sync.yaml" "$REPO_URL/system-dev/workflows/tasks-project-sync.yaml"
download_if_missing "system-dev/workflows/tasks-project-sync.local.sh" "$REPO_URL/system-dev/workflows/tasks-project-sync.local.sh"
fi
# ── 安裝/更新腳本:一開始就放進 system-dev/scripts/ ──
@@ -312,6 +330,8 @@ download_if_missing ".claude/hooks/pre-write-guard.sh" "$REPO_URL/.claude/hooks/
download_if_missing ".claude/commands/issue-handle.md" "$REPO_URL/.claude/commands/issue-handle.md"
chmod +x .claude/hooks/*.sh 2>/dev/null || true
chmod +x system-dev/workflows/*.sh 2>/dev/null || true
chmod +x system-dev/scripts/*.sh 2>/dev/null || true
# ── 依模組產生 settings.json 的 hooks 區塊 ────────
# settings.json 因模組而異,不能直接下載單一靜態檔,改條件組裝。
@@ -466,6 +486,19 @@ fi
if $WANT_SDD; then
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)"
# ── tasks⇄Project 投影:裝/init 對話 + 一次性廣告(issue #16)──
# 判準=能力(arcrun 裝了沒)+意願,不掃檔。落地成「CC 問一句」,install 只是交代 CC 去問。
echo ""
t " ❓ 待辦同步(optional,需 Arcrun):請你的 CC 問你一句——" \
" ❓ Task sync (optional, needs Arcrun): have your CC ask you once —"
t " 「您需要把本專案的待辦事項(tasks.md)同步到 GitHub 嗎?」" \
" \"Do you want this project's tasks (tasks.md) mirrored to GitHub?\""
t " 答「好」→ CC 查環境有沒有 Arcrunmcp / acr 在 PATH):有就設定同步、沒有就一次性告知" \
" Yes → CC checks for Arcrun (mcp / acr in PATH): set it up if present, otherwise inform you once"
t " 「Arcrun 是免費的 AI-friendly 工作流套件,想裝跟 Claude 說就行;之後也可手動啟用」。" \
" \"Arcrun is a free AI-friendly workflow toolkit — ask Claude to install it; you can also enable sync later.\""
t " 答「不好」→ 不做、不再追問。投影 workflow 在 system-dev/workflows/(帶檔≠啟用)。" \
" No → nothing happens, no nagging. The projection workflow sits in system-dev/workflows/ (shipped ≠ enabled)."
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)"
+53 -2
View File
@@ -23,7 +23,7 @@ esac
t() { if [ "$IS_ZH" = "yes" ]; then printf '%s\n' "$1"; else printf '%s\n' "$2"; fi; }
tn() { if [ "$IS_ZH" = "yes" ]; then printf '%s' "$1"; else printf '%s' "$2"; fi; }
REPO_RAW="https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main"
REPO_RAW="https://git.uncle6.me/Leo/system-dev-template/raw/branch/main"
TEMPLATE_URL="$REPO_RAW/template"
UPDATED=()
@@ -217,15 +217,26 @@ keep_with_template ".claude/hooks/pre-write-guard.sh" "$TEMPLATE_URL/.claude/hoo
update_file ".claude/commands/issue-handle.md" "$TEMPLATE_URL/.claude/commands/issue-handle.md"
update_file "system-dev/VERSION" "$TEMPLATE_URL/system-dev/VERSION"
# Logseq 任務 marker 解析(單一真相源):vault 萃取(/wiki-extract)與 tasks→Project
# 投影共用同一套;任一模組在用就補/更新(邏輯檔,可覆蓋)。
if $HAS_WIKI || $HAS_SDD; then
update_file "system-dev/docs/4-guides/logseq-markers.md" "$TEMPLATE_URL/system-dev/docs/4-guides/logseq-markers.md"
fi
if $HAS_WIKI; then
# 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"
# 1.16.0:讓 wiki 真的被讀到的兩支(開場 push 全文解決不了「只讀開頭」,見 CHANGELOG)
update_file ".claude/hooks/wiki-first-search.sh" "$TEMPLATE_URL/.claude/hooks/wiki-first-search.sh"
update_file ".claude/hooks/subagent-wiki-guard.sh" "$TEMPLATE_URL/.claude/hooks/subagent-wiki-guard.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"
# vault 增量萃取(Logseq/Obsidian → system-dev/wiki,冪等):邏輯檔,可覆蓋。舊版沒有 → 當新檔補。
update_file ".claude/commands/wiki-extract.md" "$TEMPLATE_URL/.claude/commands/wiki-extract.md"
# Coworkclaude.ai)的 wiki 整理 skill:規則檔,可覆蓋
update_file "system-dev/docs/SKILL.md" "$TEMPLATE_URL/system-dev/docs/SKILL.md"
@@ -246,6 +257,18 @@ if $HAS_SDD; then
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"
# SDD 生命週期鐵律(1.14,issue #6):規則檔+獨立檢查腳本=邏輯檔可覆蓋;
# pending-changes.md 裝著用戶的 proposal=用戶資料,只補不覆蓋。
# issue #13 教訓:update 不補新檔會造成結構斷層,新檔必須在這裡鋪。)
update_file "system-dev/docs/3-specs/SDD-LIFECYCLE.md" "$TEMPLATE_URL/system-dev/docs/3-specs/SDD-LIFECYCLE.md"
add_if_missing "system-dev/docs/3-specs/pending-changes.md" "$TEMPLATE_URL/system-dev/docs/3-specs/pending-changes.md"
update_file "system-dev/scripts/sdd-active-check.sh" "$TEMPLATE_URL/scripts/sdd-active-check.sh"
# tasks⇄Project 投影(issue #16):邏輯檔,可覆蓋。舊版沒有 → add_if_missing 補。
# 啟用狀態存遠端(acr push),不在這些檔裡,覆蓋不會關掉誰的同步。
add_if_missing "system-dev/workflows/tasks-project-sync.yaml" "$TEMPLATE_URL/system-dev/workflows/tasks-project-sync.yaml"
add_if_missing "system-dev/workflows/tasks-project-sync.local.sh" "$TEMPLATE_URL/system-dev/workflows/tasks-project-sync.local.sh"
fi
# ── 自我更新:把最新的 update.sh / install.sh 抓到 system-dev/scripts/ ──
@@ -253,7 +276,7 @@ fi
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 system-dev/scripts/*.sh 2>/dev/null || true
chmod +x .claude/hooks/*.sh system-dev/scripts/*.sh system-dev/workflows/*.sh 2>/dev/null || true
# ── 使用者資料檔:絕不碰,但提醒「設定可能有新欄位要手動補」──
keep_file ".claude/settings.json"
@@ -317,6 +340,34 @@ if [ -f ".claude/settings.json" ]; then
$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")
# ── 1.16.0:兩支 wiki 讀取 hook 自動註冊(不只提醒)──
# 理由:這兩支的整個存在意義就是「不依賴任何人記得」。
# 若靠人看提醒去手動補 settings.json,等於把同一個病搬到安裝環節。
if $HAS_WIKI && command -v python3 >/dev/null 2>&1; then
python3 - <<'PYEOF' 2>/dev/null || true
import json, os
p = ".claude/settings.json"
try:
with open(p) as f: d = json.load(f)
except Exception:
raise SystemExit(0) # 壞掉的 settings 不碰,交給下方提醒
pre = d.setdefault("hooks", {}).setdefault("PreToolUse", [])
blob = json.dumps(pre)
added = []
if "wiki-first-search" not in blob:
pre.append({"matcher": "Grep|Glob|Read", "hooks": [
{"type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/wiki-first-search.sh"}]})
added.append("wiki-first-search")
if "subagent-wiki-guard" not in blob:
pre.append({"matcher": "Task", "hooks": [
{"type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/subagent-wiki-guard.sh"}]})
added.append("subagent-wiki-guard")
if added:
with open(p, "w") as f: json.dump(d, f, ensure_ascii=False, indent=2)
print(" ✅ 已自動註冊 wiki 讀取 hook" + "、".join(added))
PYEOF
fi
if [ ${#MISSING[@]} -gt 0 ]; then
echo ""
t "📌 settings.json 是你的設定(沒動),但偵測到缺以下 hook,請手動補上:" \
+10 -12
View File
@@ -39,23 +39,21 @@
INDEX 是**所有檢索角度的入口**,不只標籤。原文是唯讀 SSoT,wiki 是改寫過的記憶。
新增角度只要在這裡加一節(如「決策角度」「原則角度」),指向對應 cards 或 push 檔——**不必新增實體特殊檔**。
### 子系統角度(按 `TAXONOMY.md` 的軸聚類,指向桶子索引)
### 標籤角度(按 `TAXONOMY.md` 的軸聚類,指向桶子索引)
#### 架構決策(跨子系統)
- [[decisions/00-INDEX]] — arcrun 架構決策(13 卡,已從 decisions-summary 全量改寫成原子卡)
```markdown
#### 知識管理
- [[pkm/00-INDEX]] — PKM 知識管理(N 卡)
> 子系統卡桶(零件架構 / cypher / credential / recipe / kbdb / 薄殼 / 部署)尚未獨立建——
> 決策卡已用 frontmatter `tags:` 掛子系統軸,可從 INDEX 標籤過濾;純子系統知識卡由 /wiki-capture 依需開桶。
#### AI 協作
- [[ai/00-INDEX]] — AI 協作(M 卡)
```
### 決策角度(取代舊 decisions-summary.md 的視圖)
> `decisions-summary.md`(全文)保留為相容;13 條決策已逐條改寫成 `cards/decisions/` 原子卡,入口見 [[decisions/00-INDEX]]。
> 按子系統分群的清單在桶子索引內,這裡只放跨子系統最常查的:
- [[工作流是default零件是例外]] — 自用→工作流,全生態重用→才零件(mindset §1)
- [[薄殼原則-能力長在API]] — 能力只實作一次放 API,介面全薄殼(rule 07)
- [[自力救濟階梯-缺能力怎麼補]] — 缺能力分流:自家補API/第三方 workflow 補丁(issue #4
- [[service-binding-vs-cypher-binding]] — 零件串接走 HTTP URL,禁 service bindingrule 03
```markdown
- [[某決策卡]] — 一句話結論(YYYY-MM-DD
```
> 結構:INDEX(多角度入口)→ `cards/<bucket>/00-INDEX.md`(桶子索引,固定名)→ 概念原子卡。
> 指 `00-INDEX` **一律帶路徑** `[[bucket/00-INDEX]]`(固定名跨桶撞名);卡片間用裸 `[[卡名]]`。