#!/usr/bin/env sh # inventory-tooling.sh — 盤點 jsc plugins、skills、tools、hooks,輸出技能組基礎指引。 # # 用法: inventory-tooling.sh [root] # # root: 預設取本腳本位置的上兩層(meta/tools -> meta -> 根)。 # 也可用參數或 JSC_PLUGINS_ROOT 覆寫。 # # 輸出: Markdown。內容包含 domain、manifest、技能、工具、hooks 與管理入口。 # 結束碼: 0=成功 1=根目錄、marketplace 或必要工具缺失 set -eu HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) ROOT=${1:-${JSC_PLUGINS_ROOT:-$(CDPATH= cd -- "$HERE/../.." && pwd)}} ROOT=${ROOT%/} [ -d "$ROOT" ] || { echo "找不到 plugins 根目錄:$ROOT" >&2; exit 1; } MARKETPLACE="" for cand in "$ROOT/meta/.claude-plugin/marketplace.json" "$ROOT"/*/.claude-plugin/marketplace.json; do [ -f "$cand" ] && { MARKETPLACE=$cand; break; } done [ -n "$MARKETPLACE" ] || { echo "找不到 marketplace.json,無法判定 domain 清單" >&2; exit 1; } LIST_SKILLS="$ROOT/meta/tools/list-skills.sh" [ -x "$LIST_SKILLS" ] || { echo "找不到可執行的 list-skills.sh:$LIST_SKILLS" >&2; exit 1; } tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT domains_file="$tmp/domains.tsv" skills_file="$tmp/skills.tsv" clis_file="$tmp/clis.tsv" hook_status_file="$tmp/hook-status.tsv" sed -n 's/.*"name"[[:space:]]*:[[:space:]]*"jsc-\([a-z0-9-]*\)".*/\1/p' "$MARKETPLACE" | sort -u | while read -r domain; do [ -n "$domain" ] || continue path="$ROOT/$domain" [ -d "$path" ] || path="$ROOT/jsc-$domain" if [ -d "$path" ]; then version=$(sed -n 's/.*"version": *"\([^"]*\)".*/\1/p' "$path/plugin.json" 2>/dev/null | head -1) [ -n "$version" ] || version="未知" printf '%s\t%s\t%s\n' "$domain" "$version" "$path" else printf '%s\t%s\t%s\n' "$domain" "缺本機存取庫" "-" fi done > "$domains_file" JSC_PLUGINS_ROOT="$ROOT" "$LIST_SKILLS" > "$skills_file" 2>/dev/null || : > "$skills_file" DETECT_CLIS="$ROOT/cli/tools/detect-clis.sh" if [ -x "$DETECT_CLIS" ]; then "$DETECT_CLIS" > "$clis_file" 2>/dev/null || : > "$clis_file" else : > "$clis_file" fi WIRE_CLI="$ROOT/hooks/tools/wire-cli.sh" : > "$hook_status_file" if [ -x "$WIRE_CLI" ] && [ -s "$clis_file" ]; then while IFS="$(printf '\t')" read -r cli path version; do [ -n "$cli" ] || continue out="$tmp/wire-$cli.out" err="$tmp/wire-$cli.err" if "$WIRE_CLI" status "$cli" > "$out" 2> "$err"; then rc=0 else rc=$? fi verdict=$(sed -n '1{s/[|]/-/g;p;}' "$out") [ -n "$verdict" ] || verdict=$(sed -n '1{s/[|]/-/g;p;}' "$err") [ -n "$verdict" ] || verdict="無狀態輸出" case "$rc" in 0|1|3|5) ;; 2) verdict="CLI 代號不符合 wire-cli.sh 用法" ;; *) verdict="未知狀態,結束碼 $rc" ;; esac printf '%s\t%s\t%s\n' "$cli" "$rc" "$verdict" >> "$hook_status_file" done < "$clis_file" fi count_lines() { file=$1 [ -s "$file" ] || { echo 0; return; } wc -l < "$file" | tr -d ' ' } domains_count=$(count_lines "$domains_file") skills_count=$(count_lines "$skills_file") clis_count=$(count_lines "$clis_file") cat </dev/null) [ -n "$first" ] || first="工具腳本" printf '| `%s` | `%s` | %s |\n' "$domain" "$base" "$first" done done < "$domains_file" cat <<'EOF' Tool 使用方式: - 先讀工具檔頭的用法與結束碼。 - 用真實參數驗證新增或修改的工具。 - 結束碼沒有文件化時,先補工具說明,再讓技能呼叫它。 ## Hook management | hook | 用途 | | --- | --- | EOF HOOK_DIR="$ROOT/hooks/hooks" if [ -d "$HOOK_DIR" ]; then for hook in "$HOOK_DIR"/*.sh; do [ -f "$hook" ] || continue base=$(basename "$hook") first=$(sed -n '2{s/^# *//;p;}' "$hook" 2>/dev/null) [ -n "$first" ] || first="hook 腳本" printf '| `%s` | %s |\n' "$base" "$first" done else echo '| - | 找不到 `hooks/hooks`。請先執行 `meta/tools/sync-domains.sh`。 |' fi cat <<'EOF' Hook 使用方式: - Hook 只放在 `jsc-hooks` domain。 - `jsc-hooks:hooks-install` 負責接線到各 CLI。 - hook 腳本要能接受 stdin JSON 與環境變數。 - 缺欄位時安靜降級並 `exit 0`。 - 版本閘門與重啟閘門要保留解除自己的路徑。 ## Hook wiring status | CLI | 結束碼 | 狀態 | | --- | ---: | --- | EOF if [ -s "$hook_status_file" ]; then while IFS="$(printf '\t')" read -r cli rc status; do [ -n "$cli" ] || continue printf '| `%s` | %s | %s |\n' "$cli" "$rc" "$status" done < "$hook_status_file" else echo '| - | - | 未偵測到 CLI,或找不到 `hooks/tools/wire-cli.sh`。 |' fi cat <<'EOF' ## Plugin and skill management - 新增技能:使用 `jsc-meta:skill-new`。 - 更新單一技能:使用 `jsc-meta:skill-update`。 - 批次更新技能組:使用 `jsc-meta:skillset-update`。 - 刪除技能:使用 `jsc-meta:skill-delete`。 - 安裝、更新、移除整組 plugin:使用 `jsc-cli:deploy`。 - 例行稽核:使用 `jsc-meta:skill-check`。 - 重新接線 hooks:使用 `jsc-hooks:hooks-install`。 ## Operational checks - 體檢目前環境:使用 `jsc-cli:doctor`。 - 修復體檢項目:使用 `jsc-cli:setup`。 - 版本前置檢查:由 `jsc-hooks/hooks/version-guard.sh` 管理。 - 部署後重啟閘門:由 `jsc-hooks/hooks/restart-gate.sh` 管理。 - 語言提示與掃描:由 `jsc-hooks/hooks/ste100-guard.sh` 與 `jsc-hooks/hooks/lang-guard.sh` 管理。 - 註解範圍檢查:由 `jsc-hooks/hooks/comment-scope.sh` 管理。 ## Use this when - 先執行 `meta/tools/sync-domains.sh`,同步 marketplace 上的 domain。 - 再執行 `meta/tools/list-skills.sh`,確認技能清單。 - 執行本工具,產出基礎指引。 - 若新增或修改技能,執行 `meta/tools/sync-skill-manifest.sh {domain-path}`。 - 執行 `meta/tools/ste100-lint.sh {domain-path}`。 - 依 `jsc-git:pr` 開立 Push Request。 EOF