refactor(plugin 命名空間): plugin 更名 jsc-doc、hooks 只註冊自己擁有的 worklog

- 五份 manifest 的 name 由 jsc 改為 jsc-doc
- skill 目錄去掉重複的 doc- 前綴共 5 個(doc-funcs → funcs 等),worklog 名稱不變,frontmatter name 同步
- hooks/hooks.json 由合併超集改為只註冊 Stop(worklog):role 的 hook 交還 jsc-generic,避免改名後重複執行
- hook 腳本搜尋路徑與文件內 cache 路徑改指 jsc-doc
- 指令引用改為 /jsc-doc: 前綴;跨 plugin 引用指向 /jsc-code:、/jsc-generic:
- 保留 .docs/doc-funcs-index.md 等產物檔名不變(非 skill 識別名)
- 版號 0.2.6 → 0.2.7

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jeffery
2026-07-28 17:07:14 +08:00
co-authored by Claude Opus 5
parent a1e68dafaf
commit 67106b22c3
23 changed files with 135 additions and 151 deletions
+56
View File
@@ -0,0 +1,56 @@
---
name: docker
description: 整理並對齊 docker-compose.yaml 的行內註解與標題區塊。當使用者要對齊 docker-compose 註解、整理 compose 檔註解欄位、更新 compose 標題日期,或提到 docker-compose、dc-tidy、align_comments、註解對齊時使用此 skill。
---
# 對齊 docker-compose 註解
整理並對齊 `docker-compose.yaml` 的行內註解與標題。請優先使用自動化腳本執行。
以下範例中的 `skill_dir` 是本 skill 所在目錄,也就是包含此 `SKILL.md``scripts/` 的資料夾。不要假設目標專案內存在 `plugins/skills/docker/`
## 全專案批次處理(未指定檔案時)
```bash
bash "${skill_dir}/scripts/align_comments.sh" --yes
```
## 單一檔案處理(指定檔案時)
`${file}` 為使用者指定的目標檔案:
```bash
bash "${skill_dir}/scripts/align_comments.sh" "${file}" --yes
```
## 手動執行流程參考
1. **[步驟 0] 還原空白基準**:移除既有對齊用空白,回到可重新計算的狀態。
```bash
tmp="$(mktemp "${file}.tmp.XXXXXX")" && awk -f "${skill_dir}/scripts/awk/strip_col.awk" "${file}" > "$tmp" && mv -- "$tmp" "${file}"
```
2. **[步驟 1] 校閱註解**:修正註解文字與數值正確性。
3. **[步驟 2] 計算對齊欄位**:取得對齊欄位。
```bash
awk -f "${skill_dir}/scripts/awk/find_col.awk" "${file}"
```
取得 `TARGET=XX`。
4. **[步驟 3] 執行對齊**:依 `TARGET` 欄位對齊註解。
```bash
tmp="$(mktemp "${file}.tmp.XXXXXX")" && awk -v TARGET=<TARGET> -f "${skill_dir}/scripts/awk/align_col.awk" "${file}" > "$tmp" && mv -- "$tmp" "${file}"
```
5. **[步驟 4] 驗證對齊**:驗證對齊結果。
```bash
awk -v TARGET=<TARGET> -f "${skill_dir}/scripts/awk/verify_col.awk" "${file}"
```
6. **[步驟 5] 更新日期**:更新標題區塊的 `更新日期` 為今日。
+147
View File
@@ -0,0 +1,147 @@
#!/usr/bin/env bash
# docker-compose 註解對齊工具
# 用法: bash align_comments.sh [file_or_directory] [--yes]
#
# 功能:
# 1. 如果未指定檔案,則搜尋專案中所有 docker-compose.yaml。
# 2. 每個檔案獨立計算註解對齊欄位。
# 3. 更新標題中的更新日期。
set -euo pipefail
# 參數處理
target_path=""
auto_confirm=false
had_failure=false
for arg in "$@"; do
if [[ "$arg" == "--yes" ]] || [[ "$arg" == "-y" ]]; then
auto_confirm=true
else
target_path="$arg"
fi
done
AWK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/awk"
write_with_tmp() {
local source_file="$1"
local awk_file="$2"
shift 2
local tmp_file
tmp_file="$(mktemp "${source_file}.tmp.XXXXXX")"
if awk "$@" -f "$awk_file" "$source_file" > "$tmp_file"; then
mv -- "$tmp_file" "$source_file"
else
rm -f -- "$tmp_file"
return 1
fi
}
process_file() {
local file="$1"
if [[ ! -f "$file" ]]; then
echo "Skip: $file is not a file."
return
fi
echo ">>> Processing: $file"
# 步驟 0:還原多餘空白 (Strip)
write_with_tmp "$file" "$AWK_DIR/strip_col.awk"
echo "[0] Strip done."
# 步驟 1:人工修正註解內容 (Review)
if [[ "$auto_confirm" == "false" ]]; then
echo "[1] 請檢查註解內容是否正確 ($file)。"
read -r -p "完成後按 Enter 繼續 (或輸入 's' 跳過此檔, 'a' 全部自動完成): " input
if [[ "$input" == "s" ]]; then
echo "Skipped."
return
fi
if [[ "$input" == "a" ]]; then
auto_confirm=true
fi
fi
# 步驟 2:找出最大對齊欄位 (Find)
local target
target=$(awk -f "$AWK_DIR/find_col.awk" "$file" | awk -F= '{print $2}')
if [[ -z "$target" ]] || [[ "$target" -eq 0 ]]; then
echo "[2] No inline comments found. Skipping alignment."
else
echo "[2] Calculated TARGET column: $target"
# 步驟 3:對齊 (Align)
write_with_tmp "$file" "$AWK_DIR/align_col.awk" -v TARGET="$target"
echo "[3] Align done."
# 步驟 4:驗證 (Verify)
local verify
verify=$(awk -v TARGET="$target" -f "$AWK_DIR/verify_col.awk" "$file")
if [[ -z "$verify" ]]; then
echo "[4] Verify OK."
else
echo "[4] Verify FAILED for $file:"
echo "$verify"
had_failure=true
return 1
fi
fi
# 步驟 5:更新標題日期 (Update)
local today
today=$(date +%Y-%m-%d)
# 支援不同的 sed 版本 (Linux/GNU vs BSD/MacOS)
if sed --version >/dev/null 2>&1; then
# GNU sed
sed -i "s/# 更新日期: [0-9-]*/# 更新日期: $today/" "$file"
else
# BSD sed (MacOS)
sed -i '' "s/# 更新日期: [0-9-]*/# 更新日期: $today/" "$file"
fi
echo "[5] Updated '更新日期' to $today."
echo ""
}
find_compose_files() {
local root="$1"
find "$root" \
\( -path '*/node_modules' -o -path '*/.git' -o -path '*/bin' -o -path '*/obj' \) -prune \
-o -name 'docker-compose.yaml' -type f -print0
}
process_found_files() {
local root="$1"
local found=false
while IFS= read -r -d '' file; do
found=true
process_file "$file" || had_failure=true
done < <(find_compose_files "$root")
if [[ "$found" == "false" ]]; then
echo "No docker-compose.yaml files found."
fi
}
# 執行邏輯
if [[ -z "$target_path" ]]; then
echo "No target specified. Searching for all docker-compose.yaml files in the project..."
process_found_files "."
elif [[ -d "$target_path" ]]; then
echo "Target is a directory. Searching for docker-compose.yaml files within: $target_path"
process_found_files "$target_path"
else
process_file "$target_path" || had_failure=true
fi
if [[ "$had_failure" == "true" ]]; then
echo "Done with failures."
exit 1
fi
echo "Done!"
+9
View File
@@ -0,0 +1,9 @@
!/^[[:space:]]*#/ && / #/ {
idx = index($0, " #")
if (idx > 0 && idx != TARGET) {
pad = ""
for (i = idx; i < TARGET; i++) pad = pad " "
sub(/ #/, pad " #")
}
}
{ print }
+8
View File
@@ -0,0 +1,8 @@
!/^[[:space:]]*#/ && / #/ {
idx = index($0, " #")
content = substr($0, 1, idx - 1)
gsub(/ +$/, "", content)
col = length(content) + 2
if (col > max_col) max_col = col
}
END { print "max_col=" max_col }
+8
View File
@@ -0,0 +1,8 @@
!/^[[:space:]]*#/ && / #/ {
idx = index($0, " #")
content = substr($0, 1, idx - 1)
gsub(/ +$/, "", content)
comment = substr($0, idx)
$0 = content comment
}
{ print }
+4
View File
@@ -0,0 +1,4 @@
!/^[[:space:]]*#/ && / #/ {
idx = index($0, " #")
if (idx != TARGET) print NR, "col=" idx, substr($0, 1, 80)
}
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
# 自動補全與修正 docker-compose.yaml 行內註解內容
# 用法: bash scripts/fix_comments.sh <file>
set -euo pipefail
file="${1:-}"
if [ -z "$file" ]; then
echo "請指定要處理的檔案"
exit 1
fi
tmp_file="$(mktemp "${file}.tmp.XXXXXX")"
trap 'rm -f -- "$tmp_file"' EXIT
awk '
/^[[:space:]]*#/ { print; next }
/[[:space:]]+#/ {
match($0, /[[:space:]]+#/);
code=substr($0, 1, RSTART - 1);
comment=substr($0, RSTART + RLENGTH);
gsub(/^ +| +$/, "", comment);
if (length(comment)==0) comment="TODO: 補充說明";
print code " # " comment;
next;
}
{ print }
' "$file" > "$tmp_file"
mv -- "$tmp_file" "$file"
trap - EXIT