dev-playbooks-cn 1.6.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/scripts/config-discovery.sh +260 -0
- package/scripts/install-dependencies.sh +244 -0
- package/scripts/install-skills.sh +225 -0
- package/scripts/migrate-from-openspec.sh +471 -0
- package/scripts/migrate-from-speckit.sh +734 -0
- package/scripts/sync_mcp_from_claude_to_codex.py +343 -0
- package/skills/devbooks-delivery-workflow/SKILL.md +80 -0
- package/skills/devbooks-test-owner/SKILL.md +87 -0
- package/templates/claude-commands/devbooks/apply.md +31 -0
- package/templates/claude-commands/devbooks/archive.md +25 -0
- package/templates/claude-commands/devbooks/backport.md +22 -0
- package/templates/claude-commands/devbooks/bootstrap.md +22 -0
- package/templates/claude-commands/devbooks/c4.md +22 -0
- package/templates/claude-commands/devbooks/challenger.md +22 -0
- package/templates/claude-commands/devbooks/code.md +22 -0
- package/templates/claude-commands/devbooks/debate.md +22 -0
- package/templates/claude-commands/devbooks/delivery.md +22 -0
- package/templates/claude-commands/devbooks/design.md +22 -0
- package/templates/claude-commands/devbooks/entropy.md +22 -0
- package/templates/claude-commands/devbooks/federation.md +22 -0
- package/templates/claude-commands/devbooks/gardener.md +22 -0
- package/templates/claude-commands/devbooks/impact.md +22 -0
- package/templates/claude-commands/devbooks/index.md +22 -0
- package/templates/claude-commands/devbooks/judge.md +22 -0
- package/templates/claude-commands/devbooks/plan.md +22 -0
- package/templates/claude-commands/devbooks/proposal.md +22 -0
- package/templates/claude-commands/devbooks/quick.md +24 -0
- package/templates/claude-commands/devbooks/review.md +22 -0
- package/templates/claude-commands/devbooks/router.md +24 -0
- package/templates/claude-commands/devbooks/spec.md +22 -0
- package/templates/claude-commands/devbooks/test-review.md +22 -0
- package/templates/claude-commands/devbooks/test.md +22 -0
- package/templates/dev-playbooks/docs//346/216/250/350/215/220MCP.md +8 -343
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dev-playbooks-cn",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "AI-driven spec-based development workflow",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"devbooks",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"LICENSE",
|
|
30
30
|
"bin/",
|
|
31
31
|
"templates/",
|
|
32
|
-
"skills/"
|
|
32
|
+
"skills/",
|
|
33
|
+
"scripts/"
|
|
33
34
|
],
|
|
34
35
|
"engines": {
|
|
35
36
|
"node": ">=18"
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# scripts/config-discovery.sh
|
|
3
|
+
# DevBooks Protocol Discovery Layer - 配置发现脚本
|
|
4
|
+
#
|
|
5
|
+
# 用途:发现并输出当前项目的 DevBooks 配置
|
|
6
|
+
# 返回格式:key=value(每行一个),可被 Shell 或 AI 解析
|
|
7
|
+
#
|
|
8
|
+
# 优先级:
|
|
9
|
+
# 1. .devbooks/config.yaml(优先检查 root: dev-playbooks/)
|
|
10
|
+
# 2. dev-playbooks/(无 config.yaml 时)
|
|
11
|
+
# 3. project.md(通用模板协议)
|
|
12
|
+
#
|
|
13
|
+
# 用法:
|
|
14
|
+
# ./config-discovery.sh [project-root]
|
|
15
|
+
# source <(./config-discovery.sh) # 直接导入为 shell 变量
|
|
16
|
+
#
|
|
17
|
+
# 功能:
|
|
18
|
+
# - 支持 dev-playbooks/ 路径
|
|
19
|
+
# - 自动加载 constitution.md
|
|
20
|
+
# - 纯 Bash YAML 解析(无 yq 依赖)
|
|
21
|
+
# - 弃用警告:truth_root/change_root 别名(建议迁移到 paths.specs/paths.changes)
|
|
22
|
+
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
PROJECT_ROOT="${1:-.}"
|
|
26
|
+
|
|
27
|
+
# 颜色输出(仅在 stderr)
|
|
28
|
+
log_info() { echo "[INFO] $*" >&2; }
|
|
29
|
+
log_warn() { echo "[WARN] $*" >&2; }
|
|
30
|
+
log_error() { echo "[ERROR] $*" >&2; }
|
|
31
|
+
|
|
32
|
+
# ============================================
|
|
33
|
+
# 纯 Bash YAML 解析(无 yq 依赖)
|
|
34
|
+
# ============================================
|
|
35
|
+
|
|
36
|
+
# 读取简单键值对
|
|
37
|
+
get_yaml_value() {
|
|
38
|
+
local file="$1" key="$2"
|
|
39
|
+
grep "^${key}:" "$file" 2>/dev/null | sed 's/^[^:]*: *//' | tr -d '"'"'" | tr -d '/' || true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# 读取嵌套键(一层深度)
|
|
43
|
+
get_yaml_nested_value() {
|
|
44
|
+
local file="$1" parent="$2" key="$3"
|
|
45
|
+
# 查找 parent: 下的 key:
|
|
46
|
+
awk -v parent="$parent" -v key="$key" '
|
|
47
|
+
$0 ~ "^" parent ":" { in_parent = 1; next }
|
|
48
|
+
in_parent && /^[a-z]/ { in_parent = 0 }
|
|
49
|
+
in_parent && $0 ~ "^ " key ":" {
|
|
50
|
+
gsub(/^[^:]*: */, "")
|
|
51
|
+
gsub(/["'"'"']/, "")
|
|
52
|
+
print
|
|
53
|
+
exit
|
|
54
|
+
}
|
|
55
|
+
' "$file" 2>/dev/null || true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# ============================================
|
|
59
|
+
# 解析真理根目录
|
|
60
|
+
# ============================================
|
|
61
|
+
|
|
62
|
+
resolve_truth_root() {
|
|
63
|
+
local root="$1"
|
|
64
|
+
|
|
65
|
+
# 从 config.yaml 读取 root 配置
|
|
66
|
+
if [[ -f "${root}/.devbooks/config.yaml" ]]; then
|
|
67
|
+
local config_root
|
|
68
|
+
config_root=$(get_yaml_value "${root}/.devbooks/config.yaml" "root")
|
|
69
|
+
if [[ -n "$config_root" && -d "${root}/${config_root}" ]]; then
|
|
70
|
+
echo "${config_root}"
|
|
71
|
+
return 0
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# 检查 dev-playbooks/ 目录
|
|
76
|
+
if [[ -d "${root}/dev-playbooks" ]]; then
|
|
77
|
+
echo "dev-playbooks"
|
|
78
|
+
return 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# 未找到
|
|
82
|
+
echo ""
|
|
83
|
+
return 1
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# ============================================
|
|
87
|
+
# 加载宪法
|
|
88
|
+
# ============================================
|
|
89
|
+
|
|
90
|
+
load_constitution() {
|
|
91
|
+
local config_root="$1"
|
|
92
|
+
local constitution_file="${PROJECT_ROOT}/${config_root}/constitution.md"
|
|
93
|
+
|
|
94
|
+
if [[ -f "$constitution_file" ]]; then
|
|
95
|
+
log_info "Loading constitution from: $constitution_file"
|
|
96
|
+
echo "constitution_loaded=true"
|
|
97
|
+
echo "constitution_path=${config_root}/constitution.md"
|
|
98
|
+
return 0
|
|
99
|
+
else
|
|
100
|
+
# 检查是否强制要求宪法
|
|
101
|
+
local require_constitution="false"
|
|
102
|
+
if [[ -f "${PROJECT_ROOT}/.devbooks/config.yaml" ]]; then
|
|
103
|
+
require_constitution=$(get_yaml_nested_value "${PROJECT_ROOT}/.devbooks/config.yaml" "constraints" "require_constitution")
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
if [[ "$require_constitution" == "true" ]]; then
|
|
107
|
+
log_error "Constitution file missing: $constitution_file"
|
|
108
|
+
echo "constitution_loaded=false"
|
|
109
|
+
echo "constitution_path="
|
|
110
|
+
echo "constitution_error=missing"
|
|
111
|
+
return 1
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
log_warn "Constitution file not found (optional): $constitution_file"
|
|
115
|
+
echo "constitution_loaded=false"
|
|
116
|
+
echo "constitution_path="
|
|
117
|
+
return 0
|
|
118
|
+
fi
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# ============================================
|
|
122
|
+
# 检查文件是否存在
|
|
123
|
+
# ============================================
|
|
124
|
+
|
|
125
|
+
check_file() {
|
|
126
|
+
[[ -f "$PROJECT_ROOT/$1" ]]
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
# ============================================
|
|
130
|
+
# 输出配置
|
|
131
|
+
# ============================================
|
|
132
|
+
|
|
133
|
+
output_config() {
|
|
134
|
+
echo "config_source=$1"
|
|
135
|
+
echo "protocol=$2"
|
|
136
|
+
echo "truth_root=$3"
|
|
137
|
+
echo "change_root=$4"
|
|
138
|
+
echo "agents_doc=$5"
|
|
139
|
+
|
|
140
|
+
# 可选字段
|
|
141
|
+
[[ -n "${6:-}" ]] && echo "project_profile=$6"
|
|
142
|
+
[[ -n "${7:-}" ]] && echo "apply_requires_role=$7"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# ============================================
|
|
146
|
+
# 新格式输出(Dev-Playbooks)
|
|
147
|
+
# ============================================
|
|
148
|
+
|
|
149
|
+
output_config_v2() {
|
|
150
|
+
local config_root="$1"
|
|
151
|
+
|
|
152
|
+
echo "# Dev-Playbooks Configuration"
|
|
153
|
+
echo "devbooks_version=2.0"
|
|
154
|
+
echo "config_root=${config_root}"
|
|
155
|
+
|
|
156
|
+
# 从 config.yaml 读取路径配置
|
|
157
|
+
if [[ -f "${PROJECT_ROOT}/.devbooks/config.yaml" ]]; then
|
|
158
|
+
local specs_path changes_path staged_path
|
|
159
|
+
specs_path=$(get_yaml_nested_value "${PROJECT_ROOT}/.devbooks/config.yaml" "paths" "specs")
|
|
160
|
+
changes_path=$(get_yaml_nested_value "${PROJECT_ROOT}/.devbooks/config.yaml" "paths" "changes")
|
|
161
|
+
staged_path=$(get_yaml_nested_value "${PROJECT_ROOT}/.devbooks/config.yaml" "paths" "staged")
|
|
162
|
+
|
|
163
|
+
echo "specs_dir=${config_root}/${specs_path:-specs/}"
|
|
164
|
+
echo "changes_dir=${config_root}/${changes_path:-changes/}"
|
|
165
|
+
echo "staged_dir=${config_root}/${staged_path:-specs/_staged/}"
|
|
166
|
+
else
|
|
167
|
+
echo "specs_dir=${config_root}/specs/"
|
|
168
|
+
echo "changes_dir=${config_root}/changes/"
|
|
169
|
+
echo "staged_dir=${config_root}/specs/_staged/"
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
# 适应度配置
|
|
173
|
+
if [[ -f "${PROJECT_ROOT}/.devbooks/config.yaml" ]]; then
|
|
174
|
+
local fitness_mode fitness_rules
|
|
175
|
+
fitness_mode=$(get_yaml_nested_value "${PROJECT_ROOT}/.devbooks/config.yaml" "fitness" "mode")
|
|
176
|
+
fitness_rules=$(get_yaml_nested_value "${PROJECT_ROOT}/.devbooks/config.yaml" "fitness" "rules_file")
|
|
177
|
+
|
|
178
|
+
echo "fitness_mode=${fitness_mode:-warn}"
|
|
179
|
+
echo "fitness_rules=${config_root}/${fitness_rules:-specs/architecture/fitness-rules.md}"
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# AC 追溯配置
|
|
183
|
+
if [[ -f "${PROJECT_ROOT}/.devbooks/config.yaml" ]]; then
|
|
184
|
+
local coverage_threshold
|
|
185
|
+
coverage_threshold=$(get_yaml_nested_value "${PROJECT_ROOT}/.devbooks/config.yaml" "tracing" "coverage_threshold")
|
|
186
|
+
echo "ac_coverage_threshold=${coverage_threshold:-80}"
|
|
187
|
+
fi
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# ============================================
|
|
191
|
+
# 主逻辑
|
|
192
|
+
# ============================================
|
|
193
|
+
|
|
194
|
+
main() {
|
|
195
|
+
# 解析真理根目录
|
|
196
|
+
local truth_root
|
|
197
|
+
truth_root=$(resolve_truth_root "$PROJECT_ROOT") || {
|
|
198
|
+
log_warn "No DevBooks configuration found"
|
|
199
|
+
log_warn "Searched for:"
|
|
200
|
+
log_warn " - .devbooks/config.yaml with root: dev-playbooks/"
|
|
201
|
+
log_warn " - dev-playbooks/"
|
|
202
|
+
log_warn " - dev-playbooks/project.md"
|
|
203
|
+
log_warn " - project.md"
|
|
204
|
+
|
|
205
|
+
echo "config_source=none"
|
|
206
|
+
echo "protocol=unknown"
|
|
207
|
+
echo "truth_root="
|
|
208
|
+
echo "change_root="
|
|
209
|
+
echo "agents_doc="
|
|
210
|
+
|
|
211
|
+
exit 1
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
log_info "Found configuration root: $truth_root"
|
|
215
|
+
|
|
216
|
+
# 加载宪法(如果存在)
|
|
217
|
+
load_constitution "$truth_root" || {
|
|
218
|
+
log_error "Constitution loading failed"
|
|
219
|
+
exit 1
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
# 根据目录判断协议类型
|
|
223
|
+
case "$truth_root" in
|
|
224
|
+
dev-playbooks)
|
|
225
|
+
# DevBooks 协议
|
|
226
|
+
log_info "Using DevBooks protocol"
|
|
227
|
+
|
|
228
|
+
output_config \
|
|
229
|
+
".devbooks/config.yaml" \
|
|
230
|
+
"devbooks" \
|
|
231
|
+
"${truth_root}/specs/" \
|
|
232
|
+
"${truth_root}/changes/" \
|
|
233
|
+
"${truth_root}/project.md" \
|
|
234
|
+
"${truth_root}/specs/_meta/project-profile.md" \
|
|
235
|
+
"true"
|
|
236
|
+
|
|
237
|
+
echo ""
|
|
238
|
+
output_config_v2 "$truth_root"
|
|
239
|
+
;;
|
|
240
|
+
|
|
241
|
+
*)
|
|
242
|
+
# Template 协议
|
|
243
|
+
log_info "Using template protocol"
|
|
244
|
+
|
|
245
|
+
output_config \
|
|
246
|
+
"project.md" \
|
|
247
|
+
"template" \
|
|
248
|
+
"specs/" \
|
|
249
|
+
"changes/" \
|
|
250
|
+
"project.md" \
|
|
251
|
+
"specs/_meta/project-profile.md" \
|
|
252
|
+
"false"
|
|
253
|
+
;;
|
|
254
|
+
esac
|
|
255
|
+
|
|
256
|
+
exit 0
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# 运行主函数
|
|
260
|
+
main
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# DevBooks 系统依赖安装脚本
|
|
3
|
+
# 支持 macOS (Homebrew) 和 Linux (apt/yum)
|
|
4
|
+
#
|
|
5
|
+
# 用法: ./scripts/install-dependencies.sh [--all | --minimal | --dev]
|
|
6
|
+
# --minimal 只安装必需依赖 (jq, ripgrep)
|
|
7
|
+
# --all 安装所有依赖(默认)
|
|
8
|
+
# --dev 额外安装开发依赖 (shellcheck)
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
# 颜色输出
|
|
13
|
+
RED='\033[0;31m'
|
|
14
|
+
GREEN='\033[0;32m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
NC='\033[0m' # No Color
|
|
17
|
+
|
|
18
|
+
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|
19
|
+
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
20
|
+
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
21
|
+
|
|
22
|
+
# 检测操作系统
|
|
23
|
+
detect_os() {
|
|
24
|
+
case "$(uname -s)" in
|
|
25
|
+
Darwin*) echo "macos" ;;
|
|
26
|
+
Linux*) echo "linux" ;;
|
|
27
|
+
*) echo "unknown" ;;
|
|
28
|
+
esac
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# 检测包管理器
|
|
32
|
+
detect_package_manager() {
|
|
33
|
+
if command -v brew &>/dev/null; then
|
|
34
|
+
echo "brew"
|
|
35
|
+
elif command -v apt-get &>/dev/null; then
|
|
36
|
+
echo "apt"
|
|
37
|
+
elif command -v yum &>/dev/null; then
|
|
38
|
+
echo "yum"
|
|
39
|
+
elif command -v dnf &>/dev/null; then
|
|
40
|
+
echo "dnf"
|
|
41
|
+
else
|
|
42
|
+
echo "unknown"
|
|
43
|
+
fi
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# 检查命令是否存在
|
|
47
|
+
check_command() {
|
|
48
|
+
command -v "$1" &>/dev/null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# 安装单个工具
|
|
52
|
+
install_tool() {
|
|
53
|
+
local tool="$1"
|
|
54
|
+
local pkg_manager="$2"
|
|
55
|
+
|
|
56
|
+
if check_command "$tool"; then
|
|
57
|
+
log_info "$tool 已安装 ($(which $tool))"
|
|
58
|
+
return 0
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
log_info "安装 $tool..."
|
|
62
|
+
case "$pkg_manager" in
|
|
63
|
+
brew)
|
|
64
|
+
case "$tool" in
|
|
65
|
+
radon) pip3 install radon ;;
|
|
66
|
+
gocyclo)
|
|
67
|
+
if check_command go; then
|
|
68
|
+
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
|
|
69
|
+
else
|
|
70
|
+
log_warn "跳过 gocyclo(需要 Go 环境)"
|
|
71
|
+
return 0
|
|
72
|
+
fi
|
|
73
|
+
;;
|
|
74
|
+
*) brew install "$tool" ;;
|
|
75
|
+
esac
|
|
76
|
+
;;
|
|
77
|
+
apt)
|
|
78
|
+
case "$tool" in
|
|
79
|
+
ripgrep) sudo apt-get install -y ripgrep ;;
|
|
80
|
+
radon) pip3 install radon ;;
|
|
81
|
+
scc)
|
|
82
|
+
log_warn "scc 需要手动安装: https://github.com/boyter/scc#installation"
|
|
83
|
+
return 0
|
|
84
|
+
;;
|
|
85
|
+
gocyclo)
|
|
86
|
+
if check_command go; then
|
|
87
|
+
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
|
|
88
|
+
else
|
|
89
|
+
log_warn "跳过 gocyclo(需要 Go 环境)"
|
|
90
|
+
return 0
|
|
91
|
+
fi
|
|
92
|
+
;;
|
|
93
|
+
*) sudo apt-get install -y "$tool" ;;
|
|
94
|
+
esac
|
|
95
|
+
;;
|
|
96
|
+
yum|dnf)
|
|
97
|
+
case "$tool" in
|
|
98
|
+
radon) pip3 install radon ;;
|
|
99
|
+
scc)
|
|
100
|
+
log_warn "scc 需要手动安装: https://github.com/boyter/scc#installation"
|
|
101
|
+
return 0
|
|
102
|
+
;;
|
|
103
|
+
gocyclo)
|
|
104
|
+
if check_command go; then
|
|
105
|
+
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
|
|
106
|
+
else
|
|
107
|
+
log_warn "跳过 gocyclo(需要 Go 环境)"
|
|
108
|
+
return 0
|
|
109
|
+
fi
|
|
110
|
+
;;
|
|
111
|
+
*) sudo "$pkg_manager" install -y "$tool" ;;
|
|
112
|
+
esac
|
|
113
|
+
;;
|
|
114
|
+
*)
|
|
115
|
+
log_error "未知包管理器,请手动安装 $tool"
|
|
116
|
+
return 1
|
|
117
|
+
;;
|
|
118
|
+
esac
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# 主函数
|
|
122
|
+
main() {
|
|
123
|
+
local mode="${1:---all}"
|
|
124
|
+
local os=$(detect_os)
|
|
125
|
+
local pkg_manager=$(detect_package_manager)
|
|
126
|
+
|
|
127
|
+
log_info "检测到操作系统: $os"
|
|
128
|
+
log_info "检测到包管理器: $pkg_manager"
|
|
129
|
+
echo ""
|
|
130
|
+
|
|
131
|
+
# 必需依赖
|
|
132
|
+
local required_tools=(jq ripgrep)
|
|
133
|
+
|
|
134
|
+
# 推荐依赖(复杂度计算)
|
|
135
|
+
local recommended_tools=(scc radon gocyclo)
|
|
136
|
+
|
|
137
|
+
# 开发依赖
|
|
138
|
+
local dev_tools=(shellcheck)
|
|
139
|
+
|
|
140
|
+
# 根据模式选择安装范围
|
|
141
|
+
local tools_to_install=()
|
|
142
|
+
case "$mode" in
|
|
143
|
+
--minimal)
|
|
144
|
+
tools_to_install=("${required_tools[@]}")
|
|
145
|
+
log_info "安装模式: 最小依赖"
|
|
146
|
+
;;
|
|
147
|
+
--dev)
|
|
148
|
+
tools_to_install=("${required_tools[@]}" "${recommended_tools[@]}" "${dev_tools[@]}")
|
|
149
|
+
log_info "安装模式: 全部 + 开发依赖"
|
|
150
|
+
;;
|
|
151
|
+
--all|*)
|
|
152
|
+
tools_to_install=("${required_tools[@]}" "${recommended_tools[@]}")
|
|
153
|
+
log_info "安装模式: 全部推荐依赖"
|
|
154
|
+
;;
|
|
155
|
+
esac
|
|
156
|
+
echo ""
|
|
157
|
+
|
|
158
|
+
# 安装工具
|
|
159
|
+
local failed=()
|
|
160
|
+
for tool in "${tools_to_install[@]}"; do
|
|
161
|
+
if ! install_tool "$tool" "$pkg_manager"; then
|
|
162
|
+
failed+=("$tool")
|
|
163
|
+
fi
|
|
164
|
+
done
|
|
165
|
+
echo ""
|
|
166
|
+
|
|
167
|
+
# 验证安装
|
|
168
|
+
log_info "=== 安装验证 ==="
|
|
169
|
+
echo ""
|
|
170
|
+
echo "必需工具:"
|
|
171
|
+
for tool in "${required_tools[@]}"; do
|
|
172
|
+
if check_command "$tool"; then
|
|
173
|
+
echo " ✅ $tool: $(which $tool)"
|
|
174
|
+
else
|
|
175
|
+
echo " ❌ $tool: 未安装"
|
|
176
|
+
fi
|
|
177
|
+
done
|
|
178
|
+
echo ""
|
|
179
|
+
echo "复杂度工具:"
|
|
180
|
+
for tool in "${recommended_tools[@]}"; do
|
|
181
|
+
if check_command "$tool"; then
|
|
182
|
+
echo " ✅ $tool: $(which $tool)"
|
|
183
|
+
else
|
|
184
|
+
echo " ⚠️ $tool: 未安装(可选)"
|
|
185
|
+
fi
|
|
186
|
+
done
|
|
187
|
+
echo ""
|
|
188
|
+
|
|
189
|
+
if [[ "$mode" == "--dev" ]]; then
|
|
190
|
+
echo "开发工具:"
|
|
191
|
+
for tool in "${dev_tools[@]}"; do
|
|
192
|
+
if check_command "$tool"; then
|
|
193
|
+
echo " ✅ $tool: $(which $tool)"
|
|
194
|
+
else
|
|
195
|
+
echo " ⚠️ $tool: 未安装(可选)"
|
|
196
|
+
fi
|
|
197
|
+
done
|
|
198
|
+
echo ""
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# 总结
|
|
202
|
+
if [ ${#failed[@]} -eq 0 ]; then
|
|
203
|
+
log_info "✅ 所有依赖安装完成!"
|
|
204
|
+
else
|
|
205
|
+
log_warn "以下工具安装失败,请手动安装: ${failed[*]}"
|
|
206
|
+
fi
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
# 帮助信息
|
|
210
|
+
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
|
|
211
|
+
cat << 'EOF'
|
|
212
|
+
DevBooks 系统依赖安装脚本
|
|
213
|
+
|
|
214
|
+
用法:
|
|
215
|
+
./scripts/install-dependencies.sh [选项]
|
|
216
|
+
|
|
217
|
+
选项:
|
|
218
|
+
--minimal 只安装必需依赖 (jq, ripgrep)
|
|
219
|
+
--all 安装所有推荐依赖(默认)
|
|
220
|
+
--dev 额外安装开发依赖 (shellcheck)
|
|
221
|
+
--help 显示此帮助信息
|
|
222
|
+
|
|
223
|
+
依赖说明:
|
|
224
|
+
必需依赖:
|
|
225
|
+
- jq JSON 处理(Hook 输出格式化)
|
|
226
|
+
- ripgrep 代码搜索(符号定义查找)
|
|
227
|
+
|
|
228
|
+
推荐依赖:
|
|
229
|
+
- scc 通用复杂度计算(JS/TS/Go/Java 等)
|
|
230
|
+
- radon Python 圈复杂度
|
|
231
|
+
- gocyclo Go 圈复杂度
|
|
232
|
+
|
|
233
|
+
开发依赖:
|
|
234
|
+
- shellcheck Shell 脚本静态分析
|
|
235
|
+
|
|
236
|
+
示例:
|
|
237
|
+
./scripts/install-dependencies.sh # 安装全部推荐依赖
|
|
238
|
+
./scripts/install-dependencies.sh --minimal # 只安装必需依赖
|
|
239
|
+
./scripts/install-dependencies.sh --dev # 安装全部 + 开发依赖
|
|
240
|
+
EOF
|
|
241
|
+
exit 0
|
|
242
|
+
fi
|
|
243
|
+
|
|
244
|
+
main "$@"
|