claude-apprentice 1.0.0
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/CHANGELOG.md +112 -0
- package/LICENSE +21 -0
- package/README.md +311 -0
- package/bin/apprentice.js +196 -0
- package/install.sh +92 -0
- package/package.json +38 -0
- package/templates/CLAUDE.md +60 -0
- package/templates/commands/backend.md +18 -0
- package/templates/commands/frontend.md +18 -0
- package/templates/commands/fullstack.md +18 -0
- package/templates/commands/scan-todos.md +123 -0
- package/templates/commands/spec.md +88 -0
- package/templates/memory/architecture.md +55 -0
- package/templates/memory/backend-standards.md +84 -0
- package/templates/memory/business-logic.md +59 -0
- package/templates/memory/frontend-standards.md +89 -0
- package/templates/memory/issues.md +34 -0
- package/templates/memory/learned-lessons.md +78 -0
- package/templates/memory/superpowers-config.md +46 -0
- package/templates/rules/INDEX.md +63 -0
- package/templates/rules/coding-standards.md +25 -0
- package/templates/rules/git-safety.md +9 -0
- package/templates/rules/superpowers-workflow.md +15 -0
- package/templates/scripts/auto-review.sh +77 -0
- package/templates/scripts/health-check.sh +189 -0
- package/templates/scripts/init.sh +2476 -0
- package/templates/settings.json +23 -0
- package/templates/skills/backend-workflow.md +87 -0
- package/templates/skills/code-review/SKILL.md +253 -0
- package/templates/skills/code-review/standards.md +189 -0
- package/templates/skills/frontend-workflow.md +75 -0
- package/templates/skills/fullstack-workflow.md +121 -0
- package/templates/specs/SPEC-GUIDE.md +99 -0
- package/templates/specs/active/README.md +7 -0
- package/templates/specs/archived/README.md +10 -0
- package/templates/usage-guides/README.md +84 -0
- package/templates/usage-guides/bottleneck-navigation.md +146 -0
- package/templates/usage-guides/usage-guide-v5.8.md +1261 -0
- package/templates/workflow/WORKFLOW-GUIDE.md +78 -0
|
@@ -0,0 +1,2476 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Claude Code 全栈开发环境自动初始化脚本
|
|
4
|
+
# 用法:
|
|
5
|
+
# ./init.sh # 自动检测模式
|
|
6
|
+
# ./init.sh --workspace # 强制工作区模式
|
|
7
|
+
# ./init.sh --project <dir> # 初始化指定子项目
|
|
8
|
+
# ./init.sh --scan # 只扫描不创建
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
# ===== 颜色定义 =====
|
|
14
|
+
GREEN='\033[0;32m'
|
|
15
|
+
YELLOW='\033[0;33m'
|
|
16
|
+
RED='\033[0;31m'
|
|
17
|
+
BLUE='\033[0;34m'
|
|
18
|
+
CYAN='\033[0;36m'
|
|
19
|
+
NC='\033[0m'
|
|
20
|
+
|
|
21
|
+
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
22
|
+
ok() { echo -e "${GREEN}[OK]${NC} $1"; }
|
|
23
|
+
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
24
|
+
fail() { echo -e "${RED}[FAIL]${NC} $1"; exit 1; }
|
|
25
|
+
step() { echo -e "${CYAN}==>${NC} $1"; }
|
|
26
|
+
|
|
27
|
+
# ===== 参数解析 =====
|
|
28
|
+
MODE="auto"
|
|
29
|
+
PROJECT_DIR=""
|
|
30
|
+
|
|
31
|
+
while [[ $# -gt 0 ]]; do
|
|
32
|
+
case $1 in
|
|
33
|
+
--workspace) MODE="workspace"; shift ;;
|
|
34
|
+
--project) MODE="project"; PROJECT_DIR="${2:-.}"; shift 2 ;;
|
|
35
|
+
--scan) MODE="scan"; shift ;;
|
|
36
|
+
-h|--help)
|
|
37
|
+
echo "用法: init.sh [选项]"
|
|
38
|
+
echo ""
|
|
39
|
+
echo "选项:"
|
|
40
|
+
echo " (无参数) 自动检测:单项目 or 多项目工作区"
|
|
41
|
+
echo " --workspace 强制工作区模式(扫描子目录)"
|
|
42
|
+
echo " --project <dir> 只初始化指定子项目"
|
|
43
|
+
echo " --scan 只扫描报告,不创建文件"
|
|
44
|
+
echo " -h, --help 显示帮助"
|
|
45
|
+
exit 0
|
|
46
|
+
;;
|
|
47
|
+
*)
|
|
48
|
+
# 兼容旧用法:init.sh [项目目录]
|
|
49
|
+
if [ -d "$1" ]; then
|
|
50
|
+
PROJECT_DIR="$1"
|
|
51
|
+
else
|
|
52
|
+
fail "未知参数: $1"
|
|
53
|
+
fi
|
|
54
|
+
shift
|
|
55
|
+
;;
|
|
56
|
+
esac
|
|
57
|
+
done
|
|
58
|
+
|
|
59
|
+
TARGET="${PROJECT_DIR:-.}"
|
|
60
|
+
cd "$TARGET"
|
|
61
|
+
TARGET_DIR=$(pwd)
|
|
62
|
+
WORKSPACE_NAME=$(basename "$TARGET_DIR")
|
|
63
|
+
|
|
64
|
+
# =====================================================================
|
|
65
|
+
# 项目检测函数
|
|
66
|
+
# =====================================================================
|
|
67
|
+
|
|
68
|
+
# 检测单个目录的项目类型
|
|
69
|
+
detect_project() {
|
|
70
|
+
local dir="$1"
|
|
71
|
+
local ptype="unknown"
|
|
72
|
+
local lang="unknown"
|
|
73
|
+
local backend=""
|
|
74
|
+
local frontend=""
|
|
75
|
+
local database=""
|
|
76
|
+
local build=""
|
|
77
|
+
local category="unknown" # backend / frontend / fullstack / unknown
|
|
78
|
+
|
|
79
|
+
# 检测后端
|
|
80
|
+
if [ -f "$dir/pom.xml" ]; then
|
|
81
|
+
ptype="java-maven"; lang="Java"; backend="Spring Boot"; build="Maven"; category="backend"
|
|
82
|
+
elif [ -f "$dir/build.gradle" ] || [ -f "$dir/build.gradle.kts" ]; then
|
|
83
|
+
ptype="java-gradle"; lang="Java"; backend="Spring Boot"; build="Gradle"; category="backend"
|
|
84
|
+
elif [ -f "$dir/go.mod" ]; then
|
|
85
|
+
ptype="go"; lang="Go"; backend="Gin"; build="Go Modules"; category="backend"
|
|
86
|
+
elif [ -f "$dir/requirements.txt" ] || [ -f "$dir/pyproject.toml" ] || [ -f "$dir/setup.py" ]; then
|
|
87
|
+
ptype="python"; lang="Python"; build="pip"; category="backend"
|
|
88
|
+
# 区分 FastAPI / Django
|
|
89
|
+
if [ -f "$dir/pyproject.toml" ] && grep -q "django" "$dir/pyproject.toml" 2>/dev/null; then
|
|
90
|
+
backend="Django"
|
|
91
|
+
elif [ -f "$dir/requirements.txt" ] && grep -q "django" "$dir/requirements.txt" 2>/dev/null; then
|
|
92
|
+
backend="Django"
|
|
93
|
+
else
|
|
94
|
+
backend="FastAPI"
|
|
95
|
+
fi
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# 检测前端
|
|
99
|
+
if [ -f "$dir/package.json" ]; then
|
|
100
|
+
local fe="未知"
|
|
101
|
+
if grep -q '"vue"' "$dir/package.json" 2>/dev/null; then
|
|
102
|
+
fe="Vue"
|
|
103
|
+
elif grep -q '"react"' "$dir/package.json" 2>/dev/null; then
|
|
104
|
+
fe="React"
|
|
105
|
+
elif grep -q '"@angular/core"' "$dir/package.json" 2>/dev/null; then
|
|
106
|
+
fe="Angular"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
if [ "$ptype" = "unknown" ]; then
|
|
110
|
+
ptype="frontend"; lang="JavaScript/TypeScript"; build="npm"
|
|
111
|
+
frontend="$fe"; category="frontend"
|
|
112
|
+
else
|
|
113
|
+
ptype="${ptype}-frontend"
|
|
114
|
+
frontend="$fe"; category="fullstack"
|
|
115
|
+
fi
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# 检测数据库
|
|
119
|
+
local app_yml=$(find "$dir" -maxdepth 4 -name "application.yml" -o -name "application.yaml" 2>/dev/null | head -1)
|
|
120
|
+
if [ -n "$app_yml" ]; then
|
|
121
|
+
if grep -q "mysql" "$app_yml" 2>/dev/null; then
|
|
122
|
+
database="MySQL"
|
|
123
|
+
elif grep -q "postgresql" "$app_yml" 2>/dev/null; then
|
|
124
|
+
database="PostgreSQL"
|
|
125
|
+
elif grep -q "oracle" "$app_yml" 2>/dev/null; then
|
|
126
|
+
database="Oracle"
|
|
127
|
+
fi
|
|
128
|
+
fi
|
|
129
|
+
if [ -z "$database" ] && [ -f "$dir/docker-compose.yml" ]; then
|
|
130
|
+
if grep -q "mysql" "$dir/docker-compose.yml" 2>/dev/null; then
|
|
131
|
+
database="MySQL"
|
|
132
|
+
elif grep -q "postgres" "$dir/docker-compose.yml" 2>/dev/null; then
|
|
133
|
+
database="PostgreSQL"
|
|
134
|
+
elif grep -q "redis" "$dir/docker-compose.yml" 2>/dev/null; then
|
|
135
|
+
database="Redis"
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
# 没检测到任何项目标记
|
|
140
|
+
if [ "$ptype" = "unknown" ]; then
|
|
141
|
+
return 1
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# 输出结果(通过全局变量)
|
|
145
|
+
DET_PTYPE="$ptype"
|
|
146
|
+
DET_LANG="$lang"
|
|
147
|
+
DET_BACKEND="$backend"
|
|
148
|
+
DET_FRONTEND="$frontend"
|
|
149
|
+
DET_DATABASE="$database"
|
|
150
|
+
DET_BUILD="$build"
|
|
151
|
+
DET_CATEGORY="$category"
|
|
152
|
+
return 0
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# =====================================================================
|
|
156
|
+
# 项目深度检测:扫描依赖、工具链、目录结构
|
|
157
|
+
# =====================================================================
|
|
158
|
+
|
|
159
|
+
detect_project_details() {
|
|
160
|
+
local dir="$1"
|
|
161
|
+
local ptype="$2"
|
|
162
|
+
|
|
163
|
+
DET_JAVA_VERSION=""
|
|
164
|
+
DET_SPRING_VERSION=""
|
|
165
|
+
DET_ORM=""
|
|
166
|
+
DET_TEST_FRAMEWORK=""
|
|
167
|
+
DET_API_DOC=""
|
|
168
|
+
DET_UI_LIB=""
|
|
169
|
+
DET_STATE_MGMT=""
|
|
170
|
+
DET_CSS_FRAMEWORK=""
|
|
171
|
+
DET_LINT_TOOL=""
|
|
172
|
+
DET_PYTHON_VERSION=""
|
|
173
|
+
DET_GO_VERSION=""
|
|
174
|
+
DET_CACHE=""
|
|
175
|
+
DET_MQ=""
|
|
176
|
+
DET_DIR_TREE=""
|
|
177
|
+
|
|
178
|
+
# 实际目录结构(排除无关目录,最多 60 行)
|
|
179
|
+
DET_DIR_TREE=$(find "$dir" -maxdepth 4 -type d \
|
|
180
|
+
-not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/target/*' \
|
|
181
|
+
-not -path '*/__pycache__/*' -not -path '*/.claude/*' -not -path '*/dist/*' \
|
|
182
|
+
-not -path '*/.idea/*' -not -path '*/.vscode/*' -not -path '*/venv/*' \
|
|
183
|
+
-not -path '*/.gradle/*' -not -path '*/build/*' \
|
|
184
|
+
2>/dev/null | head -60 | sort | sed "s|^$dir||" | sed 's|^/||' | grep -v '^\.$')
|
|
185
|
+
|
|
186
|
+
# ---------- Java 深度检测 ----------
|
|
187
|
+
if echo "$ptype" | grep -q "java"; then
|
|
188
|
+
# Java 版本
|
|
189
|
+
if [ -f "$dir/pom.xml" ]; then
|
|
190
|
+
DET_JAVA_VERSION=$(grep -oP '(?<=<java.version>)[^<]+' "$dir/pom.xml" 2>/dev/null || echo "")
|
|
191
|
+
DET_SPRING_VERSION=$(grep -oP '(?<=<spring-boot.version>)[^<]+' "$dir/pom.xml" 2>/dev/null \
|
|
192
|
+
|| grep -oP 'spring-boot-starter-parent.*<version>\K[^<]+' "$dir/pom.xml" 2>/dev/null || echo "")
|
|
193
|
+
# ORM
|
|
194
|
+
if grep -q "mybatis-plus" "$dir/pom.xml" 2>/dev/null; then
|
|
195
|
+
DET_ORM="MyBatis-Plus"
|
|
196
|
+
elif grep -q "mybatis" "$dir/pom.xml" 2>/dev/null; then
|
|
197
|
+
DET_ORM="MyBatis"
|
|
198
|
+
elif grep -q "spring-boot-starter-data-jpa" "$dir/pom.xml" 2>/dev/null; then
|
|
199
|
+
DET_ORM="JPA/Hibernate"
|
|
200
|
+
fi
|
|
201
|
+
# 测试
|
|
202
|
+
if grep -q "junit" "$dir/pom.xml" 2>/dev/null; then
|
|
203
|
+
DET_TEST_FRAMEWORK="JUnit 5"
|
|
204
|
+
fi
|
|
205
|
+
if grep -q "mockito" "$dir/pom.xml" 2>/dev/null; then
|
|
206
|
+
DET_TEST_FRAMEWORK="${DET_TEST_FRAMEWORK:+$DET_TEST_FRAMEWORK + }Mockito"
|
|
207
|
+
fi
|
|
208
|
+
# API 文档
|
|
209
|
+
if grep -q "springdoc" "$dir/pom.xml" 2>/dev/null; then
|
|
210
|
+
DET_API_DOC="SpringDoc (OpenAPI 3)"
|
|
211
|
+
elif grep -q "swagger" "$dir/pom.xml" 2>/dev/null; then
|
|
212
|
+
DET_API_DOC="Swagger 2"
|
|
213
|
+
elif grep -q "knife4j" "$dir/pom.xml" 2>/dev/null; then
|
|
214
|
+
DET_API_DOC="Knife4j"
|
|
215
|
+
fi
|
|
216
|
+
# 缓存
|
|
217
|
+
if grep -q "spring-boot-starter-data-redis" "$dir/pom.xml" 2>/dev/null; then
|
|
218
|
+
DET_CACHE="Redis"
|
|
219
|
+
fi
|
|
220
|
+
# MQ
|
|
221
|
+
if grep -q "rabbitmq" "$dir/pom.xml" 2>/dev/null; then
|
|
222
|
+
DET_MQ="RabbitMQ"
|
|
223
|
+
elif grep -q "kafka" "$dir/pom.xml" 2>/dev/null; then
|
|
224
|
+
DET_MQ="Kafka"
|
|
225
|
+
elif grep -q "rocketmq" "$dir/pom.xml" 2>/dev/null; then
|
|
226
|
+
DET_MQ="RocketMQ"
|
|
227
|
+
fi
|
|
228
|
+
elif [ -f "$dir/build.gradle" ] || [ -f "$dir/build.gradle.kts" ]; then
|
|
229
|
+
local gradle_file=$(ls "$dir"/build.gradle* 2>/dev/null | head -1)
|
|
230
|
+
DET_JAVA_VERSION=$(grep -oP '(?<=sourceCompatibility.*=.*")[^"]+' "$gradle_file" 2>/dev/null \
|
|
231
|
+
|| grep -oP '(?<=javaVersion.*=.*")[^"]+' "$gradle_file" 2>/dev/null || echo "")
|
|
232
|
+
if grep -q "mybatis" "$gradle_file" 2>/dev/null; then
|
|
233
|
+
DET_ORM="MyBatis"
|
|
234
|
+
elif grep -q "jpa" "$gradle_file" 2>/dev/null; then
|
|
235
|
+
DET_ORM="JPA/Hibernate"
|
|
236
|
+
fi
|
|
237
|
+
if grep -q "springdoc" "$gradle_file" 2>/dev/null; then
|
|
238
|
+
DET_API_DOC="SpringDoc (OpenAPI 3)"
|
|
239
|
+
elif grep -q "swagger" "$gradle_file" 2>/dev/null; then
|
|
240
|
+
DET_API_DOC="Swagger 2"
|
|
241
|
+
fi
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# ---------- Python 深度检测 ----------
|
|
246
|
+
if echo "$ptype" | grep -q "python"; then
|
|
247
|
+
# Python 版本
|
|
248
|
+
if [ -f "$dir/pyproject.toml" ]; then
|
|
249
|
+
DET_PYTHON_VERSION=$(grep -oP '(?<=python-requires.*=.*">=)[^"]+' "$dir/pyproject.toml" 2>/dev/null \
|
|
250
|
+
|| grep -oP '(?<=python_requires.*=.*">=)[^"]+' "$dir/pyproject.toml" 2>/dev/null || echo "")
|
|
251
|
+
fi
|
|
252
|
+
local req_file=""
|
|
253
|
+
[ -f "$dir/requirements.txt" ] && req_file="$dir/requirements.txt"
|
|
254
|
+
[ -f "$dir/pyproject.toml" ] && req_file="$dir/pyproject.toml"
|
|
255
|
+
if [ -n "$req_file" ]; then
|
|
256
|
+
# ORM
|
|
257
|
+
if grep -q "sqlalchemy" "$req_file" 2>/dev/null; then
|
|
258
|
+
DET_ORM="SQLAlchemy"
|
|
259
|
+
elif grep -q "tortoise" "$req_file" 2>/dev/null; then
|
|
260
|
+
DET_ORM="Tortoise ORM"
|
|
261
|
+
elif grep -q "django-orm" "$req_file" 2>/dev/null || grep -q "Django" "$req_file" 2>/dev/null; then
|
|
262
|
+
DET_ORM="Django ORM"
|
|
263
|
+
fi
|
|
264
|
+
# 测试
|
|
265
|
+
if grep -q "pytest" "$req_file" 2>/dev/null; then
|
|
266
|
+
DET_TEST_FRAMEWORK="pytest"
|
|
267
|
+
fi
|
|
268
|
+
# 缓存
|
|
269
|
+
if grep -q "redis" "$req_file" 2>/dev/null; then
|
|
270
|
+
DET_CACHE="Redis"
|
|
271
|
+
fi
|
|
272
|
+
# MQ
|
|
273
|
+
if grep -q "celery" "$req_file" 2>/dev/null; then
|
|
274
|
+
DET_MQ="Celery"
|
|
275
|
+
elif grep -q "rabbitmq" "$req_file" 2>/dev/null; then
|
|
276
|
+
DET_MQ="RabbitMQ"
|
|
277
|
+
fi
|
|
278
|
+
fi
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
# ---------- Go 深度检测 ----------
|
|
282
|
+
if echo "$ptype" | grep -q "^go"; then
|
|
283
|
+
if [ -f "$dir/go.mod" ]; then
|
|
284
|
+
DET_GO_VERSION=$(head -1 "$dir/go.mod" | grep -oP 'go \K[0-9.]+' 2>/dev/null || echo "")
|
|
285
|
+
if grep -q "gin-gonic" "$dir/go.mod" 2>/dev/null; then
|
|
286
|
+
: # 已在 detect_project 中设置
|
|
287
|
+
elif grep -q "labstack/echo" "$dir/go.mod" 2>/dev/null; then
|
|
288
|
+
DET_BACKEND="Echo"
|
|
289
|
+
elif grep -q "fiber" "$dir/go.mod" 2>/dev/null; then
|
|
290
|
+
DET_BACKEND="Fiber"
|
|
291
|
+
fi
|
|
292
|
+
if grep -q "gorm.io" "$dir/go.mod" 2>/dev/null; then
|
|
293
|
+
DET_ORM="GORM"
|
|
294
|
+
elif grep -q "sqlx" "$dir/go.mod" 2>/dev/null; then
|
|
295
|
+
DET_ORM="sqlx"
|
|
296
|
+
fi
|
|
297
|
+
if grep -q "swaggo/swag" "$dir/go.mod" 2>/dev/null; then
|
|
298
|
+
DET_API_DOC="Swag (OpenAPI)"
|
|
299
|
+
fi
|
|
300
|
+
if grep -q "go-redis" "$dir/go.mod" 2>/dev/null; then
|
|
301
|
+
DET_CACHE="Redis"
|
|
302
|
+
fi
|
|
303
|
+
fi
|
|
304
|
+
fi
|
|
305
|
+
|
|
306
|
+
# ---------- 前端深度检测 ----------
|
|
307
|
+
if echo "$ptype" | grep -q "frontend" && [ -f "$dir/package.json" ]; then
|
|
308
|
+
# UI 组件库
|
|
309
|
+
if grep -q '"element-plus"' "$dir/package.json" 2>/dev/null; then
|
|
310
|
+
DET_UI_LIB="Element Plus"
|
|
311
|
+
elif grep -q '"ant-design-vue"' "$dir/package.json" 2>/dev/null; then
|
|
312
|
+
DET_UI_LIB="Ant Design Vue"
|
|
313
|
+
elif grep -q '"vuetify"' "$dir/package.json" 2>/dev/null; then
|
|
314
|
+
DET_UI_LIB="Vuetify"
|
|
315
|
+
elif grep -q '"@arco-design/web-vue"' "$dir/package.json" 2>/dev/null; then
|
|
316
|
+
DET_UI_LIB="Arco Design Vue"
|
|
317
|
+
elif grep -q '"antd"' "$dir/package.json" 2>/dev/null; then
|
|
318
|
+
DET_UI_LIB="Ant Design"
|
|
319
|
+
elif grep -q '"@mui/material"' "$dir/package.json" 2>/dev/null; then
|
|
320
|
+
DET_UI_LIB="Material UI"
|
|
321
|
+
elif grep -q '"@chakra-ui"' "$dir/package.json" 2>/dev/null; then
|
|
322
|
+
DET_UI_LIB="Chakra UI"
|
|
323
|
+
fi
|
|
324
|
+
|
|
325
|
+
# 状态管理
|
|
326
|
+
if grep -q '"pinia"' "$dir/package.json" 2>/dev/null; then
|
|
327
|
+
DET_STATE_MGMT="Pinia"
|
|
328
|
+
elif grep -q '"vuex"' "$dir/package.json" 2>/dev/null; then
|
|
329
|
+
DET_STATE_MGMT="Vuex"
|
|
330
|
+
elif grep -q '"@reduxjs/toolkit"' "$dir/package.json" 2>/dev/null; then
|
|
331
|
+
DET_STATE_MGMT="Redux Toolkit"
|
|
332
|
+
elif grep -q '"zustand"' "$dir/package.json" 2>/dev/null; then
|
|
333
|
+
DET_STATE_MGMT="Zustand"
|
|
334
|
+
elif grep -q '"mobx"' "$dir/package.json" 2>/dev/null; then
|
|
335
|
+
DET_STATE_MGMT="MobX"
|
|
336
|
+
fi
|
|
337
|
+
|
|
338
|
+
# CSS 框架
|
|
339
|
+
if grep -q '"tailwindcss"' "$dir/package.json" 2>/dev/null; then
|
|
340
|
+
DET_CSS_FRAMEWORK="Tailwind CSS"
|
|
341
|
+
elif grep -q '"sass"' "$dir/package.json" 2>/dev/null; then
|
|
342
|
+
DET_CSS_FRAMEWORK="SCSS/Sass"
|
|
343
|
+
elif grep -q '"less"' "$dir/package.json" 2>/dev/null; then
|
|
344
|
+
DET_CSS_FRAMEWORK="Less"
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
# 测试
|
|
348
|
+
if grep -q '"vitest"' "$dir/package.json" 2>/dev/null; then
|
|
349
|
+
DET_TEST_FRAMEWORK="Vitest"
|
|
350
|
+
elif grep -q '"jest"' "$dir/package.json" 2>/dev/null; then
|
|
351
|
+
DET_TEST_FRAMEWORK="Jest"
|
|
352
|
+
fi
|
|
353
|
+
if grep -q '"cypress"' "$dir/package.json" 2>/dev/null; then
|
|
354
|
+
DET_TEST_FRAMEWORK="${DET_TEST_FRAMEWORK:+$DET_TEST_FRAMEWORK + }Cypress"
|
|
355
|
+
elif grep -q '"@playwright/test"' "$dir/package.json" 2>/dev/null; then
|
|
356
|
+
DET_TEST_FRAMEWORK="${DET_TEST_FRAMEWORK:+$DET_TEST_FRAMEWORK + }Playwright"
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
# Lint
|
|
360
|
+
if grep -q '"eslint"' "$dir/package.json" 2>/dev/null; then
|
|
361
|
+
DET_LINT_TOOL="ESLint"
|
|
362
|
+
fi
|
|
363
|
+
if grep -q '"prettier"' "$dir/package.json" 2>/dev/null; then
|
|
364
|
+
DET_LINT_TOOL="${DET_LINT_TOOL:+$DET_LINT_TOOL + }Prettier"
|
|
365
|
+
fi
|
|
366
|
+
fi
|
|
367
|
+
|
|
368
|
+
return 0
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
# 扫描所有子项目
|
|
372
|
+
scan_subprojects() {
|
|
373
|
+
SUBPROJECTS=()
|
|
374
|
+
BACKEND_PROJECTS=()
|
|
375
|
+
FRONTEND_PROJECTS=()
|
|
376
|
+
|
|
377
|
+
local root_has_project=false
|
|
378
|
+
if detect_project "."; then
|
|
379
|
+
root_has_project=true
|
|
380
|
+
SUBPROJECTS+=(".|${WORKSPACE_NAME}|${DET_PTYPE}|${DET_LANG}|${DET_BACKEND}|${DET_FRONTEND}|${DET_DATABASE}|${DET_BUILD}|${DET_CATEGORY}")
|
|
381
|
+
if [ "$DET_CATEGORY" = "backend" ] || [ "$DET_CATEGORY" = "fullstack" ]; then
|
|
382
|
+
BACKEND_PROJECTS+=(".|${WORKSPACE_NAME}|${DET_PTYPE}|${DET_BACKEND}")
|
|
383
|
+
fi
|
|
384
|
+
if [ "$DET_CATEGORY" = "frontend" ] || [ "$DET_CATEGORY" = "fullstack" ]; then
|
|
385
|
+
FRONTEND_PROJECTS+=(".|${WORKSPACE_NAME}|${DET_PTYPE}|${DET_FRONTEND}")
|
|
386
|
+
fi
|
|
387
|
+
fi
|
|
388
|
+
|
|
389
|
+
# 扫描一级子目录
|
|
390
|
+
for subdir in */; do
|
|
391
|
+
[ "$subdir" = "node_modules/" ] && continue
|
|
392
|
+
[ "$subdir" = ".claude/" ] && continue
|
|
393
|
+
[ "$subdir" = "docs/" ] && continue
|
|
394
|
+
[ ! -d "$subdir" ] && continue
|
|
395
|
+
|
|
396
|
+
local subdir_name="${subdir%/}"
|
|
397
|
+
if detect_project "$subdir_name"; then
|
|
398
|
+
SUBPROJECTS+=("${subdir_name}|${subdir_name}|${DET_PTYPE}|${DET_LANG}|${DET_BACKEND}|${DET_FRONTEND}|${DET_DATABASE}|${DET_BUILD}|${DET_CATEGORY}")
|
|
399
|
+
if [ "$DET_CATEGORY" = "backend" ] || [ "$DET_CATEGORY" = "fullstack" ]; then
|
|
400
|
+
BACKEND_PROJECTS+=("${subdir_name}|${subdir_name}|${DET_PTYPE}|${DET_BACKEND}")
|
|
401
|
+
fi
|
|
402
|
+
if [ "$DET_CATEGORY" = "frontend" ] || [ "$DET_CATEGORY" = "fullstack" ]; then
|
|
403
|
+
FRONTEND_PROJECTS+=("${subdir_name}|${subdir_name}|${DET_PTYPE}|${DET_FRONTEND}")
|
|
404
|
+
fi
|
|
405
|
+
fi
|
|
406
|
+
done
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
# 打印扫描结果
|
|
410
|
+
print_scan_results() {
|
|
411
|
+
echo ""
|
|
412
|
+
echo "========================================"
|
|
413
|
+
echo -e "${CYAN} 项目扫描结果${NC}"
|
|
414
|
+
echo "========================================"
|
|
415
|
+
echo ""
|
|
416
|
+
|
|
417
|
+
if [ ${#SUBPROJECTS[@]} -eq 0 ]; then
|
|
418
|
+
warn "未检测到任何项目"
|
|
419
|
+
return
|
|
420
|
+
fi
|
|
421
|
+
|
|
422
|
+
printf " %-20s %-12s %-20s %-15s %-10s\n" "项目" "类型" "技术栈" "框架" "分类"
|
|
423
|
+
printf " %-20s %-12s %-20s %-15s %-10s\n" "----" "----" "-------" "----" "----"
|
|
424
|
+
|
|
425
|
+
for proj in "${SUBPROJECTS[@]}"; do
|
|
426
|
+
IFS='|' read -r path name ptype lang backend frontend database build category <<< "$proj"
|
|
427
|
+
local tech="$lang"
|
|
428
|
+
local framework=""
|
|
429
|
+
[ -n "$backend" ] && framework="$backend"
|
|
430
|
+
[ -n "$frontend" ] && framework="${framework:+$framework / }$frontend"
|
|
431
|
+
printf " %-20s %-12s %-20s %-15s %-10s\n" "$name" "$category" "$tech" "$framework" "$ptype"
|
|
432
|
+
done
|
|
433
|
+
|
|
434
|
+
echo ""
|
|
435
|
+
info "后端项目: ${#BACKEND_PROJECTS[@]} 个"
|
|
436
|
+
info "前端项目: ${#FRONTEND_PROJECTS[@]} 个"
|
|
437
|
+
info "总计: ${#SUBPROJECTS[@]} 个项目"
|
|
438
|
+
echo ""
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
# =====================================================================
|
|
442
|
+
# 生成函数:settings.json
|
|
443
|
+
# =====================================================================
|
|
444
|
+
|
|
445
|
+
generate_settings() {
|
|
446
|
+
local target_dir="$1"
|
|
447
|
+
local is_workspace="$2" # "true" or "false"
|
|
448
|
+
|
|
449
|
+
if [ -f "$target_dir/.claude/settings.json" ]; then
|
|
450
|
+
info "settings.json 已存在,跳过"
|
|
451
|
+
return
|
|
452
|
+
fi
|
|
453
|
+
|
|
454
|
+
if [ "$is_workspace" = "true" ]; then
|
|
455
|
+
cat > "$target_dir/.claude/settings.json" << 'SETTINGEOF'
|
|
456
|
+
{
|
|
457
|
+
"language": "chinese",
|
|
458
|
+
"theme": "auto",
|
|
459
|
+
"permissions": {
|
|
460
|
+
"allow": [
|
|
461
|
+
"Bash(npm *)",
|
|
462
|
+
"Bash(mvn *)",
|
|
463
|
+
"Bash(gradle *)",
|
|
464
|
+
"Bash(go *)",
|
|
465
|
+
"Bash(python *)",
|
|
466
|
+
"Bash(pip *)",
|
|
467
|
+
"Bash(node *)",
|
|
468
|
+
"Bash(git show *)",
|
|
469
|
+
"Bash(git diff *)",
|
|
470
|
+
"Bash(git log *)",
|
|
471
|
+
"Bash(git diff-tree *)",
|
|
472
|
+
"Read(*)",
|
|
473
|
+
"Edit(*)",
|
|
474
|
+
"Write(*)"
|
|
475
|
+
],
|
|
476
|
+
"deny": [
|
|
477
|
+
"Bash(git push --force)",
|
|
478
|
+
"Bash(rm -rf *)"
|
|
479
|
+
]
|
|
480
|
+
},
|
|
481
|
+
"enabledPlugins": {
|
|
482
|
+
"superpowers@superpowers-marketplace": true,
|
|
483
|
+
"document-skills@anthropic-agent-skills": true
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
SETTINGEOF
|
|
487
|
+
else
|
|
488
|
+
# 单项目配置 — 根据技术栈定制权限
|
|
489
|
+
local extra_perms=""
|
|
490
|
+
if echo "$1" | grep -q "java" 2>/dev/null || [ -f "$target_dir/pom.xml" ]; then
|
|
491
|
+
extra_perms="\"Bash(mvn *)\", \"Bash(gradle *)\","
|
|
492
|
+
elif [ -f "$target_dir/go.mod" ]; then
|
|
493
|
+
extra_perms="\"Bash(go *)\","
|
|
494
|
+
elif [ -f "$target_dir/requirements.txt" ] || [ -f "$target_dir/pyproject.toml" ]; then
|
|
495
|
+
extra_perms="\"Bash(python *)\", \"Bash(pip *)\","
|
|
496
|
+
fi
|
|
497
|
+
|
|
498
|
+
if [ -f "$target_dir/package.json" ]; then
|
|
499
|
+
extra_perms="${extra_perms}\"Bash(npm *)\", \"Bash(node *)\","
|
|
500
|
+
fi
|
|
501
|
+
|
|
502
|
+
cat > "$target_dir/.claude/settings.json" << SETTINGEOF
|
|
503
|
+
{
|
|
504
|
+
"language": "chinese",
|
|
505
|
+
"theme": "auto",
|
|
506
|
+
"permissions": {
|
|
507
|
+
"allow": [
|
|
508
|
+
${extra_perms}
|
|
509
|
+
"Bash(git show *)",
|
|
510
|
+
"Bash(git diff *)",
|
|
511
|
+
"Bash(git log *)",
|
|
512
|
+
"Bash(git diff-tree *)",
|
|
513
|
+
"Read(*)",
|
|
514
|
+
"Edit(*)",
|
|
515
|
+
"Write(*)"
|
|
516
|
+
],
|
|
517
|
+
"deny": [
|
|
518
|
+
"Bash(git push --force)",
|
|
519
|
+
"Bash(rm -rf *)"
|
|
520
|
+
]
|
|
521
|
+
},
|
|
522
|
+
"enabledPlugins": {
|
|
523
|
+
"superpowers@superpowers-marketplace": true,
|
|
524
|
+
"document-skills@anthropic-agent-skills": true
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
SETTINGEOF
|
|
528
|
+
fi
|
|
529
|
+
ok "settings.json 已创建"
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
# =====================================================================
|
|
533
|
+
# 生成函数:共享 rules
|
|
534
|
+
# =====================================================================
|
|
535
|
+
|
|
536
|
+
generate_shared_rules() {
|
|
537
|
+
local target_dir="$1"
|
|
538
|
+
local rules_dir="$target_dir/.claude/rules"
|
|
539
|
+
mkdir -p "$rules_dir"
|
|
540
|
+
|
|
541
|
+
# Git 安全规则
|
|
542
|
+
if [ ! -f "$rules_dir/git-safety.md" ]; then
|
|
543
|
+
cat > "$rules_dir/git-safety.md" << 'EOF'
|
|
544
|
+
<important if="running git commands or creating commits">
|
|
545
|
+
Git 安全规则:
|
|
546
|
+
|
|
547
|
+
- 不执行 `git push --force`
|
|
548
|
+
- 不执行 `rm -rf`
|
|
549
|
+
- 不跳过 hooks(不使用 --no-verify)
|
|
550
|
+
- 创建新 commit 而非 amend(除非明确要求)
|
|
551
|
+
- 不提交含密钥的文件(.env、credentials 等)
|
|
552
|
+
</important>
|
|
553
|
+
EOF
|
|
554
|
+
fi
|
|
555
|
+
|
|
556
|
+
# 开发铁律 + 调试规则
|
|
557
|
+
if [ ! -f "$rules_dir/superpowers-workflow.md" ]; then
|
|
558
|
+
cat > "$rules_dir/superpowers-workflow.md" << 'EOF'
|
|
559
|
+
<important if="executing any workflow skill">
|
|
560
|
+
Workflow 执行规则:
|
|
561
|
+
|
|
562
|
+
1. 没设计不写代码 — 先确认文件、范围、方案
|
|
563
|
+
2. 没测试不写代码 — 先写失败测试,再写实现
|
|
564
|
+
3. 没验证不说完成 — 运行验证命令并贴结果
|
|
565
|
+
</important>
|
|
566
|
+
|
|
567
|
+
<important if="encountering a bug or test failure">
|
|
568
|
+
调试规则:
|
|
569
|
+
|
|
570
|
+
- 先找根因再修,不靠猜
|
|
571
|
+
- 读堆栈 → 复现 → 追踪数据流 → 假设 → 最小改动验证
|
|
572
|
+
- 连续 3 次失败,停下来审视架构
|
|
573
|
+
</important>
|
|
574
|
+
EOF
|
|
575
|
+
fi
|
|
576
|
+
|
|
577
|
+
# 基础编码标准
|
|
578
|
+
if [ ! -f "$rules_dir/coding-standards.md" ]; then
|
|
579
|
+
cat > "$rules_dir/coding-standards.md" << 'EOF'
|
|
580
|
+
<important if="editing any source code file">
|
|
581
|
+
编码标准:
|
|
582
|
+
|
|
583
|
+
- 不引入安全漏洞(SQL 注入、XSS、命令注入等 OWASP Top 10)
|
|
584
|
+
- 不添加超出任务需求的抽象或功能
|
|
585
|
+
- 不写多余注释,只在 WHY 不明显时注释
|
|
586
|
+
- 命名清晰即可,不写解释 WHAT 的注释
|
|
587
|
+
</important>
|
|
588
|
+
EOF
|
|
589
|
+
fi
|
|
590
|
+
|
|
591
|
+
ok "共享 rules 已创建"
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
# =====================================================================
|
|
595
|
+
# 生成函数:技术栈专属 rules
|
|
596
|
+
# =====================================================================
|
|
597
|
+
|
|
598
|
+
generate_tech_rules() {
|
|
599
|
+
local target_dir="$1"
|
|
600
|
+
local ptype="$2"
|
|
601
|
+
local rules_dir="$target_dir/.claude/rules"
|
|
602
|
+
mkdir -p "$rules_dir"
|
|
603
|
+
|
|
604
|
+
# Java / Spring Boot
|
|
605
|
+
if echo "$ptype" | grep -q "java"; then
|
|
606
|
+
if [ ! -f "$rules_dir/spring-boot.md" ]; then
|
|
607
|
+
cat > "$rules_dir/spring-boot.md" << 'EOF'
|
|
608
|
+
<important if="creating or modifying Java/Spring Boot code">
|
|
609
|
+
Spring Boot 开发规范:
|
|
610
|
+
|
|
611
|
+
- Controller 层:只接收请求、参数校验(@Valid),不写业务逻辑
|
|
612
|
+
- Service 层:业务逻辑、事务管理(@Transactional),可调用 Mapper 或其他 Service
|
|
613
|
+
- Mapper/DAO 层:数据访问,只写 SQL 映射,不含业务逻辑
|
|
614
|
+
- 禁止跨层调用(Controller 不能直接调 Mapper)
|
|
615
|
+
- 统一响应格式:{ code, message, data, timestamp }
|
|
616
|
+
- 全局异常处理:@RestControllerAdvice
|
|
617
|
+
- 表名小写下划线,必备字段 id, created_at, updated_at
|
|
618
|
+
- 使用 MyBatis-Plus 时,复杂查询手写 XML,简单 CRUD 用注解
|
|
619
|
+
</important>
|
|
620
|
+
EOF
|
|
621
|
+
ok "Java/Spring Boot rules 已创建"
|
|
622
|
+
fi
|
|
623
|
+
fi
|
|
624
|
+
|
|
625
|
+
# Python / FastAPI
|
|
626
|
+
if echo "$ptype" | grep -q "python"; then
|
|
627
|
+
if [ ! -f "$rules_dir/python-api.md" ]; then
|
|
628
|
+
cat > "$rules_dir/python-api.md" << 'EOF'
|
|
629
|
+
<important if="creating or modifying Python code">
|
|
630
|
+
Python 后端开发规范:
|
|
631
|
+
|
|
632
|
+
- Router 层:路由定义、请求参数校验(Pydantic Model)
|
|
633
|
+
- Service 层:业务逻辑,可调用 Model 或其他 Service
|
|
634
|
+
- Model 层:数据模型定义(SQLAlchemy / Tortoise ORM)
|
|
635
|
+
- 禁止跨层调用
|
|
636
|
+
- 异步优先:async/await,数据库 IO 不阻塞
|
|
637
|
+
- 使用 Pydantic 做请求/响应校验,不手动 if-else 校验
|
|
638
|
+
- 统一响应格式:{ code, message, data, timestamp }
|
|
639
|
+
- 类型注解全覆盖,不使用 Any
|
|
640
|
+
</important>
|
|
641
|
+
EOF
|
|
642
|
+
ok "Python/FastAPI rules 已创建"
|
|
643
|
+
fi
|
|
644
|
+
fi
|
|
645
|
+
|
|
646
|
+
# Vue
|
|
647
|
+
if echo "$ptype" | grep -q "frontend"; then
|
|
648
|
+
if grep -q '"vue"' "$target_dir/package.json" 2>/dev/null; then
|
|
649
|
+
if [ ! -f "$rules_dir/vue-standards.md" ]; then
|
|
650
|
+
cat > "$rules_dir/vue-standards.md" << 'EOF'
|
|
651
|
+
<important if="creating or modifying Vue code">
|
|
652
|
+
Vue 开发规范:
|
|
653
|
+
|
|
654
|
+
- 使用 Composition API + <script setup>,不使用 Options API
|
|
655
|
+
- 组件文件名 PascalCase(如 UserList.vue),新增前先搜索已有组件
|
|
656
|
+
- 状态管理使用 Pinia,不使用 Vuex
|
|
657
|
+
- API 调用统一通过 api/ 目录模块,不直接写 axios/fetch
|
|
658
|
+
- 处理 loading / error / empty 三种 UI 状态
|
|
659
|
+
- Props 定义使用 withDefaults + defineProps<T>()
|
|
660
|
+
- 组件内逻辑拆分:useXxx() composable,保持组件简洁
|
|
661
|
+
- CSS 使用 scoped,不使用全局样式污染
|
|
662
|
+
</important>
|
|
663
|
+
EOF
|
|
664
|
+
ok "Vue rules 已创建"
|
|
665
|
+
fi
|
|
666
|
+
elif grep -q '"react"' "$target_dir/package.json" 2>/dev/null; then
|
|
667
|
+
if [ ! -f "$rules_dir/react-standards.md" ]; then
|
|
668
|
+
cat > "$rules_dir/react-standards.md" << 'EOF'
|
|
669
|
+
<important if="creating or modifying React code">
|
|
670
|
+
React 开发规范:
|
|
671
|
+
|
|
672
|
+
- 使用函数组件 + Hooks,不使用类组件
|
|
673
|
+
- 组件文件名 PascalCase(如 UserList.tsx),新增前先搜索已有组件
|
|
674
|
+
- 状态管理:简单用 useState/useReducer,复杂用 Zustand 或 Redux Toolkit
|
|
675
|
+
- API 调用统一通过 api/ 目录模块,不直接写 fetch/axios
|
|
676
|
+
- 处理 loading / error / empty 三种 UI 状态
|
|
677
|
+
- 自定义 Hook 以 use 前缀命名(如 useUserInfo)
|
|
678
|
+
- Props 使用 TypeScript interface 定义
|
|
679
|
+
- 避免 useEffect 副作用地狱,依赖数组必须完整
|
|
680
|
+
</important>
|
|
681
|
+
EOF
|
|
682
|
+
ok "React rules 已创建"
|
|
683
|
+
fi
|
|
684
|
+
else
|
|
685
|
+
# 通用前端
|
|
686
|
+
if [ ! -f "$rules_dir/frontend-base.md" ]; then
|
|
687
|
+
cat > "$rules_dir/frontend-base.md" << 'EOF'
|
|
688
|
+
<important if="creating or modifying frontend code">
|
|
689
|
+
前端规范:
|
|
690
|
+
|
|
691
|
+
- 组件文件名 PascalCase,新增前先搜索已有组件
|
|
692
|
+
- API 调用统一通过 api/ 目录模块,不直接写 fetch/axios
|
|
693
|
+
- 处理 loading / error / empty 三种状态
|
|
694
|
+
- ESLint + Prettier 规则不可绕过
|
|
695
|
+
</important>
|
|
696
|
+
EOF
|
|
697
|
+
ok "前端通用 rules 已创建"
|
|
698
|
+
fi
|
|
699
|
+
fi
|
|
700
|
+
fi
|
|
701
|
+
|
|
702
|
+
# Go
|
|
703
|
+
if echo "$ptype" | grep -q "^go"; then
|
|
704
|
+
if [ ! -f "$rules_dir/go-standards.md" ]; then
|
|
705
|
+
cat > "$rules_dir/go-standards.md" << 'EOF'
|
|
706
|
+
<important if="creating or modifying Go code">
|
|
707
|
+
Go 开发规范:
|
|
708
|
+
|
|
709
|
+
- Handler 层:接收请求、参数绑定(ShouldBind),不写业务逻辑
|
|
710
|
+
- Service 层:业务逻辑,可调用 Repository 或其他 Service
|
|
711
|
+
- Repository 层:数据访问,不含业务逻辑
|
|
712
|
+
- 禁止跨层调用
|
|
713
|
+
- 错误处理:不忽略 error,必须处理或向上传递
|
|
714
|
+
- 使用标准 layout:cmd/、internal/、pkg/ 结构
|
|
715
|
+
- 统一响应格式:{ code, message, data, timestamp }
|
|
716
|
+
- Context 传递:所有函数第一参数接收 ctx context.Context
|
|
717
|
+
- 数据库操作使用事务确保一致性
|
|
718
|
+
</important>
|
|
719
|
+
EOF
|
|
720
|
+
ok "Go rules 已创建"
|
|
721
|
+
fi
|
|
722
|
+
fi
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
# =====================================================================
|
|
726
|
+
# 生成函数:commands
|
|
727
|
+
# =====================================================================
|
|
728
|
+
|
|
729
|
+
generate_commands() {
|
|
730
|
+
local target_dir="$1"
|
|
731
|
+
local mode="$2" # "single" / "workspace"
|
|
732
|
+
local backend_list="$3"
|
|
733
|
+
local frontend_list="$4"
|
|
734
|
+
local cmds_dir="$target_dir/.claude/commands"
|
|
735
|
+
mkdir -p "$cmds_dir"
|
|
736
|
+
|
|
737
|
+
if [ "$mode" = "workspace" ]; then
|
|
738
|
+
# 工作区命令 — 带子项目感知
|
|
739
|
+
|
|
740
|
+
# /frontend
|
|
741
|
+
if [ ! -f "$cmds_dir/frontend.md" ]; then
|
|
742
|
+
local fe_hint=""
|
|
743
|
+
if [ ${#FRONTEND_PROJECTS[@]} -gt 0 ]; then
|
|
744
|
+
fe_hint=$'\n## 前端子项目\n'
|
|
745
|
+
for p in "${FRONTEND_PROJECTS[@]}"; do
|
|
746
|
+
IFS='|' read -r path name ptype framework <<< "$p"
|
|
747
|
+
fe_hint+="- \`$name\` ($framework) — cd $name 后使用\n"
|
|
748
|
+
done
|
|
749
|
+
fi
|
|
750
|
+
cat > "$cmds_dir/frontend.md" << EOF
|
|
751
|
+
切换到前端开发模式。从现在起,你的工作重点是 UI 组件开发、样式调整、状态管理、前端性能优化。
|
|
752
|
+
${fe_hint}
|
|
753
|
+
## 约束
|
|
754
|
+
|
|
755
|
+
- 代码风格遵循当前项目的 \`.claude/memory/frontend-standards.md\`
|
|
756
|
+
- API 调用统一走 \`api/\` 目录模块,不直接写 HTTP 请求
|
|
757
|
+
- 组件保持单一职责,PascalCase 命名,新增前先搜索已有组件
|
|
758
|
+
- 处理好加载/错误/空状态三种 UI 反馈
|
|
759
|
+
- ESLint + Prettier 规则不可绕过
|
|
760
|
+
|
|
761
|
+
## 下一步
|
|
762
|
+
|
|
763
|
+
- **简单任务**(改样式/改文案):直接描述需求即可
|
|
764
|
+
- **中等任务**(新组件/新页面):说"帮我设计一下",会触发 brainstorming
|
|
765
|
+
- **复杂任务**(新功能模块):说"帮我规划",会走完整流程
|
|
766
|
+
|
|
767
|
+
\$ARGUMENTS
|
|
768
|
+
EOF
|
|
769
|
+
fi
|
|
770
|
+
|
|
771
|
+
# /backend
|
|
772
|
+
if [ ! -f "$cmds_dir/backend.md" ]; then
|
|
773
|
+
local be_hint=""
|
|
774
|
+
if [ ${#BACKEND_PROJECTS[@]} -gt 0 ]; then
|
|
775
|
+
be_hint=$'\n## 后端子项目\n'
|
|
776
|
+
for p in "${BACKEND_PROJECTS[@]}"; do
|
|
777
|
+
IFS='|' read -r path name ptype framework <<< "$p"
|
|
778
|
+
be_hint+="- \`$name\` ($framework) — cd $name 后使用\n"
|
|
779
|
+
done
|
|
780
|
+
fi
|
|
781
|
+
cat > "$cmds_dir/backend.md" << EOF
|
|
782
|
+
切换到后端开发模式。从现在起,你的工作重点是 API 接口设计、数据库操作、业务逻辑、服务治理。
|
|
783
|
+
${be_hint}
|
|
784
|
+
## 约束
|
|
785
|
+
|
|
786
|
+
- 代码风格遵循当前项目的 \`.claude/memory/backend-standards.md\`
|
|
787
|
+
- 严格分层架构,禁止跨层调用
|
|
788
|
+
- API 使用 RESTful 风格,统一响应格式 \`{ code, message, data, timestamp }\`
|
|
789
|
+
- 所有外部输入必须校验,防止 SQL 注入和 XSS
|
|
790
|
+
|
|
791
|
+
## 下一步
|
|
792
|
+
|
|
793
|
+
- **简单任务**(修接口/加字段):直接描述需求即可
|
|
794
|
+
- **中等任务**(新接口/新表):说"帮我设计一下",会触发 brainstorming
|
|
795
|
+
- **复杂任务**(新模块/重构):说"帮我规划",会走完整流程
|
|
796
|
+
|
|
797
|
+
\$ARGUMENTS
|
|
798
|
+
EOF
|
|
799
|
+
fi
|
|
800
|
+
|
|
801
|
+
# /fullstack
|
|
802
|
+
if [ ! -f "$cmds_dir/fullstack.md" ]; then
|
|
803
|
+
cat > "$cmds_dir/fullstack.md" << 'EOF'
|
|
804
|
+
切换到全栈协调模式。从现在起,你需要同时关注前后端一致性和完整数据流。
|
|
805
|
+
|
|
806
|
+
## 多项目工作区
|
|
807
|
+
|
|
808
|
+
本工作区包含多个子项目,全栈模式需要协调跨项目的数据流。
|
|
809
|
+
|
|
810
|
+
## 约束
|
|
811
|
+
|
|
812
|
+
- 前后端数据格式必须统一,接口契约必须一致
|
|
813
|
+
- 开发顺序:数据库 → 后端 API → 前端页面,自底向上
|
|
814
|
+
- 前端 API 调用必须与后端接口定义匹配(字段名、类型、路径)
|
|
815
|
+
- 错误处理链路完整:数据库异常 → 后端异常处理 → 前端错误展示
|
|
816
|
+
|
|
817
|
+
## 下一步
|
|
818
|
+
|
|
819
|
+
- **简单任务**(改字段/修 bug):直接描述需求即可
|
|
820
|
+
- **中等任务**(新页面+新接口):说"帮我设计一下",会触发 brainstorming
|
|
821
|
+
- **复杂任务**(新功能模块):说"帮我规划",会走完整流程
|
|
822
|
+
|
|
823
|
+
$ARGUMENTS
|
|
824
|
+
EOF
|
|
825
|
+
fi
|
|
826
|
+
|
|
827
|
+
else
|
|
828
|
+
# 单项目命令 — 同当前逻辑
|
|
829
|
+
if [ ! -f "$cmds_dir/frontend.md" ]; then
|
|
830
|
+
cat > "$cmds_dir/frontend.md" << 'EOF'
|
|
831
|
+
切换到前端开发模式。从现在起,你的工作重点是 UI 组件开发、样式调整、状态管理、前端性能优化。
|
|
832
|
+
|
|
833
|
+
## 约束
|
|
834
|
+
|
|
835
|
+
- 代码风格遵循 `.claude/memory/frontend-standards.md`
|
|
836
|
+
- API 调用统一走 `api/` 目录模块,不直接写 HTTP 请求
|
|
837
|
+
- 组件保持单一职责,PascalCase 命名,新增前先搜索已有组件
|
|
838
|
+
- 处理好加载/错误/空状态三种 UI 反馈
|
|
839
|
+
- ESLint + Prettier 规则不可绕过
|
|
840
|
+
|
|
841
|
+
## 下一步
|
|
842
|
+
|
|
843
|
+
- **简单任务**(改样式/改文案):直接描述需求即可
|
|
844
|
+
- **中等任务**(新组件/新页面):说"帮我设计一下",会触发 brainstorming
|
|
845
|
+
- **复杂任务**(新功能模块):说"帮我规划",会走完整流程
|
|
846
|
+
- **完整流程**:调用 `/frontend-workflow` 走结构化开发流水线
|
|
847
|
+
|
|
848
|
+
$ARGUMENTS
|
|
849
|
+
EOF
|
|
850
|
+
fi
|
|
851
|
+
|
|
852
|
+
if [ ! -f "$cmds_dir/backend.md" ]; then
|
|
853
|
+
cat > "$cmds_dir/backend.md" << 'EOF'
|
|
854
|
+
切换到后端开发模式。从现在起,你的工作重点是 API 接口设计、数据库操作、业务逻辑、服务治理。
|
|
855
|
+
|
|
856
|
+
## 约束
|
|
857
|
+
|
|
858
|
+
- 代码风格遵循 `.claude/memory/backend-standards.md`
|
|
859
|
+
- 严格分层架构:Controller → Service → DAO/Mapper,禁止跨层调用
|
|
860
|
+
- API 使用 RESTful 风格,统一响应格式 `{ code, message, data, timestamp }`
|
|
861
|
+
- 表名小写下划线,必备字段 `id, created_at, updated_at`
|
|
862
|
+
- 所有外部输入必须校验,防止 SQL 注入和 XSS
|
|
863
|
+
|
|
864
|
+
## 下一步
|
|
865
|
+
|
|
866
|
+
- **简单任务**(修接口/加字段):直接描述需求即可
|
|
867
|
+
- **中等任务**(新接口/新表):说"帮我设计一下",会触发 brainstorming
|
|
868
|
+
- **复杂任务**(新模块/重构):说"帮我规划",会走完整流程
|
|
869
|
+
- **完整流程**:调用 `/backend-workflow` 走结构化开发流水线
|
|
870
|
+
|
|
871
|
+
$ARGUMENTS
|
|
872
|
+
EOF
|
|
873
|
+
fi
|
|
874
|
+
|
|
875
|
+
if [ ! -f "$cmds_dir/fullstack.md" ]; then
|
|
876
|
+
cat > "$cmds_dir/fullstack.md" << 'EOF'
|
|
877
|
+
切换到全栈协调模式。从现在起,你需要同时关注前后端一致性和完整数据流。
|
|
878
|
+
|
|
879
|
+
## 约束
|
|
880
|
+
|
|
881
|
+
- 后端遵循 `.claude/memory/backend-standards.md`,前端遵循 `.claude/memory/frontend-standards.md`
|
|
882
|
+
- 前后端数据格式必须统一,接口契约必须一致
|
|
883
|
+
- 开发顺序:数据库 → 后端 API → 前端页面,自底向上
|
|
884
|
+
- 前端 API 调用必须与后端接口定义匹配(字段名、类型、路径)
|
|
885
|
+
- 错误处理链路完整:数据库异常 → 后端异常处理 → 前端错误展示
|
|
886
|
+
|
|
887
|
+
## 下一步
|
|
888
|
+
|
|
889
|
+
- **简单任务**(改字段/修 bug):直接描述需求即可
|
|
890
|
+
- **中等任务**(新页面+新接口):说"帮我设计一下",会触发 brainstorming
|
|
891
|
+
- **复杂任务**(新功能模块):说"帮我规划",会走 brainstorming → planning → TDD 完整流程
|
|
892
|
+
- **完整流程**:调用 `/fullstack-workflow` 走结构化全栈开发流水线
|
|
893
|
+
|
|
894
|
+
$ARGUMENTS
|
|
895
|
+
EOF
|
|
896
|
+
fi
|
|
897
|
+
fi
|
|
898
|
+
|
|
899
|
+
ok "commands 已创建"
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
# =====================================================================
|
|
903
|
+
# 生成函数:skills
|
|
904
|
+
# =====================================================================
|
|
905
|
+
|
|
906
|
+
generate_skills() {
|
|
907
|
+
local target_dir="$1"
|
|
908
|
+
local skills_dir="$target_dir/.claude/skills"
|
|
909
|
+
mkdir -p "$skills_dir"
|
|
910
|
+
|
|
911
|
+
# 前端 Skill
|
|
912
|
+
if [ ! -f "$skills_dir/frontend-workflow.md" ]; then
|
|
913
|
+
cat > "$skills_dir/frontend-workflow.md" << 'SKILLEOF'
|
|
914
|
+
---
|
|
915
|
+
name: frontend-workflow
|
|
916
|
+
description: 当需要开发或修改前端 UI 组件、页面、样式、状态管理、前端性能优化时使用
|
|
917
|
+
context: fork
|
|
918
|
+
---
|
|
919
|
+
|
|
920
|
+
# 前端开发流程编排器
|
|
921
|
+
|
|
922
|
+
你处于前端开发模式。本技能是完整的前端开发流程编排器,每个步骤关联 Superpowers Skill,根据项目配置决定是否启用。
|
|
923
|
+
|
|
924
|
+
## 配置读取(流程开始前执行)
|
|
925
|
+
|
|
926
|
+
读取 `.claude/memory/superpowers-config.md` 中的配置,确定每个 Skill 的启用状态:
|
|
927
|
+
- **enabled** → 对应步骤始终执行
|
|
928
|
+
- **disabled** → 对应步骤始终跳过
|
|
929
|
+
- **conditional** → 根据复杂度判断
|
|
930
|
+
|
|
931
|
+
复杂度:简单(单文件 < 30 分钟)/ 中等(新组件 30 分钟 - 2 小时)/ 复杂(新模块 > 2 小时)
|
|
932
|
+
|
|
933
|
+
---
|
|
934
|
+
|
|
935
|
+
## 流程步骤
|
|
936
|
+
|
|
937
|
+
### 步骤 0:需求入口 [必选]
|
|
938
|
+
|
|
939
|
+
- 接收用户需求描述
|
|
940
|
+
- 判断复杂度等级
|
|
941
|
+
- **简单任务**(改样式/改文案)→ 跳到步骤 3 直接实现
|
|
942
|
+
- **中等/复杂任务** → 进入步骤 1
|
|
943
|
+
|
|
944
|
+
### 步骤 1:需求澄清与方案设计 [中等+复杂]
|
|
945
|
+
|
|
946
|
+
- 确认涉及的文件、组件、页面
|
|
947
|
+
- 检查 `.claude/memory/frontend-standards.md` 了解项目规范
|
|
948
|
+
- 搜索项目中是否已有可复用的组件
|
|
949
|
+
- 在 `specs/active/` 创建 spec 文件
|
|
950
|
+
- 输出设计要点让用户确认
|
|
951
|
+
|
|
952
|
+
### 步骤 2:任务拆解与计划 [复杂]
|
|
953
|
+
|
|
954
|
+
- 拆解为 2-5 分钟可完成的小任务
|
|
955
|
+
- 输出计划让用户确认
|
|
956
|
+
|
|
957
|
+
### 步骤 3:实现 [必选]
|
|
958
|
+
|
|
959
|
+
- 按规范编写代码
|
|
960
|
+
- API 调用通过 `api/` 目录模块
|
|
961
|
+
- 处理 loading / error / empty 三种状态
|
|
962
|
+
|
|
963
|
+
### 步骤 4:验证 [必选]
|
|
964
|
+
|
|
965
|
+
- 运行 lint 和测试(如存在)
|
|
966
|
+
- 贴出运行结果作为完成证据
|
|
967
|
+
- 已完成的 spec 移入 `specs/archived/`
|
|
968
|
+
|
|
969
|
+
---
|
|
970
|
+
|
|
971
|
+
## 完成标准
|
|
972
|
+
|
|
973
|
+
- lint 无错误 + 测试通过 + 三种状态已处理 + 符合规范 + 验证结果已贴出
|
|
974
|
+
SKILLEOF
|
|
975
|
+
fi
|
|
976
|
+
|
|
977
|
+
# 后端 Skill
|
|
978
|
+
if [ ! -f "$skills_dir/backend-workflow.md" ]; then
|
|
979
|
+
cat > "$skills_dir/backend-workflow.md" << 'SKILLEOF'
|
|
980
|
+
---
|
|
981
|
+
name: backend-workflow
|
|
982
|
+
description: 当需要开发或修改后端 API 接口、数据库操作、业务逻辑、服务配置时使用
|
|
983
|
+
context: fork
|
|
984
|
+
---
|
|
985
|
+
|
|
986
|
+
# 后端开发流程编排器
|
|
987
|
+
|
|
988
|
+
你处于后端开发模式。本技能是完整的后端开发流程编排器,每个步骤关联 Superpowers Skill,根据项目配置决定是否启用。
|
|
989
|
+
|
|
990
|
+
## 配置读取(流程开始前执行)
|
|
991
|
+
|
|
992
|
+
读取 `.claude/memory/superpowers-config.md` 中的配置,确定每个 Skill 的启用状态:
|
|
993
|
+
- **enabled** → 对应步骤始终执行
|
|
994
|
+
- **disabled** → 对应步骤始终跳过
|
|
995
|
+
- **conditional** → 根据复杂度判断
|
|
996
|
+
|
|
997
|
+
复杂度:简单(单接口/加字段 < 30 分钟)/ 中等(新表+新接口 30 分钟 - 2 小时)/ 复杂(新模块 > 2 小时)
|
|
998
|
+
|
|
999
|
+
---
|
|
1000
|
+
|
|
1001
|
+
## 流程步骤
|
|
1002
|
+
|
|
1003
|
+
### 步骤 0:需求入口 [必选]
|
|
1004
|
+
|
|
1005
|
+
- 接收用户需求描述
|
|
1006
|
+
- 判断复杂度等级
|
|
1007
|
+
- **简单任务**(修接口/加字段)→ 跳到步骤 3 直接实现
|
|
1008
|
+
- **中等/复杂任务** → 进入步骤 1
|
|
1009
|
+
|
|
1010
|
+
### 步骤 1:需求澄清与方案设计 [中等+复杂]
|
|
1011
|
+
|
|
1012
|
+
- 确认涉及的业务模块、数据表、接口
|
|
1013
|
+
- 设计 API 路径、请求参数、响应格式、错误码
|
|
1014
|
+
- 设计数据库变更(如需建表/改表,先输出 DDL)
|
|
1015
|
+
- 在 `specs/active/` 创建 spec 文件
|
|
1016
|
+
- 输出设计要点让用户确认
|
|
1017
|
+
|
|
1018
|
+
### 步骤 2:任务拆解与计划 [复杂]
|
|
1019
|
+
|
|
1020
|
+
- 拆解为 2-5 分钟可完成的小任务
|
|
1021
|
+
- 输出计划让用户确认
|
|
1022
|
+
|
|
1023
|
+
### 步骤 3:自底向上实现 [必选]
|
|
1024
|
+
|
|
1025
|
+
按顺序逐层实现:
|
|
1026
|
+
1. **DAO/Mapper 层** — 数据访问方法、SQL 映射
|
|
1027
|
+
2. **Service 层** — 业务逻辑、事务管理
|
|
1028
|
+
3. **Controller 层** — 接口定义、参数校验、响应封装
|
|
1029
|
+
|
|
1030
|
+
### 步骤 4:验证 [必选]
|
|
1031
|
+
|
|
1032
|
+
- 运行构建和测试命令
|
|
1033
|
+
- 贴出运行结果作为完成证据
|
|
1034
|
+
- 已完成的 spec 移入 `specs/archived/`
|
|
1035
|
+
|
|
1036
|
+
---
|
|
1037
|
+
|
|
1038
|
+
## 完成标准
|
|
1039
|
+
|
|
1040
|
+
- 编译通过 + 测试通过 + 分层正确 + 无安全隐患 + 验证结果已贴出
|
|
1041
|
+
SKILLEOF
|
|
1042
|
+
fi
|
|
1043
|
+
|
|
1044
|
+
# 全栈 Skill
|
|
1045
|
+
if [ ! -f "$skills_dir/fullstack-workflow.md" ]; then
|
|
1046
|
+
cat > "$skills_dir/fullstack-workflow.md" << 'SKILLEOF'
|
|
1047
|
+
---
|
|
1048
|
+
name: fullstack-workflow
|
|
1049
|
+
description: 当需要开发完整功能模块(从数据库到前端页面)或进行前后端联调时使用
|
|
1050
|
+
context: fork
|
|
1051
|
+
---
|
|
1052
|
+
|
|
1053
|
+
# 全栈开发流程编排器
|
|
1054
|
+
|
|
1055
|
+
你处于全栈协调模式。本技能是完整的开发流程编排器。
|
|
1056
|
+
|
|
1057
|
+
## 配置读取(流程开始前执行)
|
|
1058
|
+
|
|
1059
|
+
读取 `.claude/memory/superpowers-config.md` 中的配置,确定每个 Skill 的启用状态。
|
|
1060
|
+
|
|
1061
|
+
---
|
|
1062
|
+
|
|
1063
|
+
## 流程步骤
|
|
1064
|
+
|
|
1065
|
+
### 步骤 0:需求入口 [必选]
|
|
1066
|
+
|
|
1067
|
+
- 接收用户需求描述
|
|
1068
|
+
- 判断复杂度等级
|
|
1069
|
+
|
|
1070
|
+
### 步骤 1:需求澄清与方案设计 [中等+复杂]
|
|
1071
|
+
|
|
1072
|
+
- 确认功能边界:数据表、接口数量、页面数量
|
|
1073
|
+
- 在 `specs/active/` 创建 spec 文件
|
|
1074
|
+
- 输出设计要点让用户确认
|
|
1075
|
+
|
|
1076
|
+
### 步骤 2:任务拆解与计划 [复杂]
|
|
1077
|
+
|
|
1078
|
+
- 拆解为 2-5 分钟可完成的小任务
|
|
1079
|
+
- 输出计划让用户确认
|
|
1080
|
+
|
|
1081
|
+
### 步骤 3:工作空间隔离 [复杂]
|
|
1082
|
+
|
|
1083
|
+
- 创建 git worktree 隔离开发环境
|
|
1084
|
+
|
|
1085
|
+
### 步骤 4:实现 [必选]
|
|
1086
|
+
|
|
1087
|
+
#### 4a. 接口契约设计
|
|
1088
|
+
- 定义 API 路径、请求/响应 JSON、错误码
|
|
1089
|
+
|
|
1090
|
+
#### 4b. 自底向上实现
|
|
1091
|
+
1. 数据库层 → 2. DAO/Mapper 层 → 3. Service 层 → 4. Controller 层 → 5. 前端 API 模块 → 6. 前端页面
|
|
1092
|
+
|
|
1093
|
+
### 步骤 5:联调验证 [必选]
|
|
1094
|
+
|
|
1095
|
+
- 运行后端构建和测试
|
|
1096
|
+
- 运行前端 lint 和测试
|
|
1097
|
+
- 验证前后端字段名/类型完全一致
|
|
1098
|
+
|
|
1099
|
+
### 步骤 6:代码审查 [中等+复杂]
|
|
1100
|
+
|
|
1101
|
+
- 按严重度分级审查
|
|
1102
|
+
|
|
1103
|
+
### 步骤 7:收尾 [必选]
|
|
1104
|
+
|
|
1105
|
+
- 更新知识库
|
|
1106
|
+
- 清理工作空间
|
|
1107
|
+
|
|
1108
|
+
---
|
|
1109
|
+
|
|
1110
|
+
## 完成标准
|
|
1111
|
+
|
|
1112
|
+
- 后端编译通过 + 测试通过 + 前端 lint 无错误 + 端到端数据流通畅 + 验证结果已贴出
|
|
1113
|
+
SKILLEOF
|
|
1114
|
+
fi
|
|
1115
|
+
|
|
1116
|
+
# 代码评审 Skill
|
|
1117
|
+
mkdir -p "$skills_dir/code-review"
|
|
1118
|
+
if [ ! -f "$skills_dir/code-review/SKILL.md" ]; then
|
|
1119
|
+
cat > "$skills_dir/code-review/SKILL.md" << 'SKILLEOF'
|
|
1120
|
+
---
|
|
1121
|
+
name: code-review
|
|
1122
|
+
description: Use when reviewing code changes, pull requests, or performing code quality audits. Triggers include mentions of "code review", "review PR", "check code quality", "代码评审", "代码审查", "评审代码", or when examining code for security vulnerabilities, correctness issues, performance problems, or maintainability concerns.
|
|
1123
|
+
---
|
|
1124
|
+
|
|
1125
|
+
# 代码评审
|
|
1126
|
+
|
|
1127
|
+
基于 6 维度 31 项评审标准体系,对代码变更进行系统性评审,输出结构化评审报告。
|
|
1128
|
+
|
|
1129
|
+
## 评审流程
|
|
1130
|
+
|
|
1131
|
+
```dot
|
|
1132
|
+
digraph review_flow {
|
|
1133
|
+
"确定评审范围" [shape=box];
|
|
1134
|
+
"读取变更内容" [shape=box];
|
|
1135
|
+
"按维度逐项检查" [shape=box];
|
|
1136
|
+
"发现高危/严重问题?" [shape=diamond];
|
|
1137
|
+
"记录问题到报告" [shape=box];
|
|
1138
|
+
"汇总评审结论" [shape=box];
|
|
1139
|
+
"输出评审报告" [shape=doublecircle];
|
|
1140
|
+
|
|
1141
|
+
"确定评审范围" -> "读取变更内容";
|
|
1142
|
+
"读取变更内容" -> "按维度逐项检查";
|
|
1143
|
+
"按维度逐项检查" -> "发现高危/严重问题?" ;
|
|
1144
|
+
"发现高危/严重问题?" -> "记录问题到报告" [label="是"];
|
|
1145
|
+
"发现高危/严重问题?" -> "汇总评审结论" [label="否,检查完毕"];
|
|
1146
|
+
"记录问题到报告" -> "按维度逐项检查";
|
|
1147
|
+
"汇总评审结论" -> "输出评审报告";
|
|
1148
|
+
}
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
## 执行步骤
|
|
1152
|
+
|
|
1153
|
+
### 1. 确定评审范围
|
|
1154
|
+
|
|
1155
|
+
根据用户输入确定评审对象:
|
|
1156
|
+
|
|
1157
|
+
**模式 A:基于 git 提交记录(推荐)**
|
|
1158
|
+
|
|
1159
|
+
询问用户选择评审方式:
|
|
1160
|
+
- **最近一次提交** → 直接使用最新 commit
|
|
1161
|
+
- **选择历史提交** → 列出最近 10 次提交,让用户选择
|
|
1162
|
+
|
|
1163
|
+
用户选择后,获取该提交涉及的文件列表,然后进入步骤 2。
|
|
1164
|
+
|
|
1165
|
+
**模式 B:指定文件或目录**
|
|
1166
|
+
|
|
1167
|
+
- 指定文件路径 → 评审该文件
|
|
1168
|
+
- 指定目录 → 评审目录下所有代码文件
|
|
1169
|
+
|
|
1170
|
+
### 2. 获取文件内容(纯读取)
|
|
1171
|
+
|
|
1172
|
+
> **重要:从本步骤开始,整个评审过程中禁止执行任何 git 命令。**
|
|
1173
|
+
|
|
1174
|
+
使用 `Read` 工具逐一读取步骤 1 中确定的文件列表。只能使用 `Read`、`Glob` 等只读工具获取文件内容。
|
|
1175
|
+
|
|
1176
|
+
### 3. 按维度逐项检查
|
|
1177
|
+
|
|
1178
|
+
严格按以下 6 个维度顺序检查,每项给出判定结果:
|
|
1179
|
+
|
|
1180
|
+
**维度优先级**:安全性 > 正确性 > 性能 > 设计与架构 > 可维护性 > 规范与一致性
|
|
1181
|
+
|
|
1182
|
+
对每个维度,逐项检查并标记:
|
|
1183
|
+
- **通过** — 符合标准
|
|
1184
|
+
- **不通过** — 不符合标准,记录具体问题和严重等级
|
|
1185
|
+
- **不适用** — 当前变更不涉及此项
|
|
1186
|
+
|
|
1187
|
+
### 4. 输出评审报告
|
|
1188
|
+
|
|
1189
|
+
评审报告格式如下:
|
|
1190
|
+
|
|
1191
|
+
```markdown
|
|
1192
|
+
# 代码评审报告
|
|
1193
|
+
|
|
1194
|
+
**评审范围**:[文件/目录/变更范围]
|
|
1195
|
+
**评审日期**:[日期]
|
|
1196
|
+
**评审结果**:[通过 | 有条件通过 | 不通过]
|
|
1197
|
+
|
|
1198
|
+
## 评审汇总
|
|
1199
|
+
|
|
1200
|
+
| 维度 | 通过 | 不通过 | 不适用 | 最高等级 |
|
|
1201
|
+
|------|------|--------|--------|---------|
|
|
1202
|
+
| 正确性与功能 | X | X | X | - |
|
|
1203
|
+
| 安全性 | X | X | X | - |
|
|
1204
|
+
| 可维护性 | X | X | X | - |
|
|
1205
|
+
| 性能 | X | X | X | - |
|
|
1206
|
+
| 设计与架构 | X | X | X | - |
|
|
1207
|
+
| 规范与一致性 | X | X | X | - |
|
|
1208
|
+
|
|
1209
|
+
## 问题清单
|
|
1210
|
+
|
|
1211
|
+
| # | 维度 | 评审项 | 问题描述 | 严重等级 | 修复建议 |
|
|
1212
|
+
|---|------|--------|---------|---------|---------|
|
|
1213
|
+
| 1 | 安全性 | SQL 注入 | ... | 高危 | ... |
|
|
1214
|
+
|
|
1215
|
+
## 评审结论
|
|
1216
|
+
|
|
1217
|
+
[总结性说明,包括必须修复的问题和建议改进项]
|
|
1218
|
+
```
|
|
1219
|
+
|
|
1220
|
+
## 评审标准速查
|
|
1221
|
+
|
|
1222
|
+
### 维度一:正确性与功能(5 项)
|
|
1223
|
+
|
|
1224
|
+
| # | 评审项 | 等级 | 检查要点 |
|
|
1225
|
+
|---|--------|------|---------|
|
|
1226
|
+
| 1.1 | 功能逻辑 | 严重 | 实现与需求一致,路径覆盖完整 |
|
|
1227
|
+
| 1.2 | 边界与异常处理 | 严重 | 空值、越界、并发、极端输入处理 |
|
|
1228
|
+
| 1.3 | 数据一致性 | 严重 | 事务正确,无竞态条件 |
|
|
1229
|
+
| 1.4 | API 契约 | 严重 | 接口约定一致,向后兼容 |
|
|
1230
|
+
| 1.5 | 测试覆盖 | 一般 | 核心逻辑有有效测试 |
|
|
1231
|
+
|
|
1232
|
+
### 维度二:安全性(18 项)
|
|
1233
|
+
|
|
1234
|
+
**业务数据篡改**:必填项/负值/一致性/选择框/置灰项/空值/边界值校验
|
|
1235
|
+
|
|
1236
|
+
**未授权访问**:登录校验、权限校验
|
|
1237
|
+
|
|
1238
|
+
**越权防护**:水平越权、ID 遍历、垂直越权
|
|
1239
|
+
|
|
1240
|
+
**信息泄露**:敏感数据脱敏、组件版本号、异常信息、密钥泄露
|
|
1241
|
+
|
|
1242
|
+
**注入攻击**:SQL 注入、CSRF、会话固定、URL 跳转、用户名枚举
|
|
1243
|
+
|
|
1244
|
+
**前端安全**:安全配置、静态文件泄露
|
|
1245
|
+
|
|
1246
|
+
> 详细标准见 standards.md
|
|
1247
|
+
|
|
1248
|
+
### 维度三:可维护性(6 项)
|
|
1249
|
+
|
|
1250
|
+
命名规范、方法长度、代码复杂度、重复代码、注释质量、依赖管理
|
|
1251
|
+
|
|
1252
|
+
### 维度四:性能(4 项)
|
|
1253
|
+
|
|
1254
|
+
数据库查询、资源管理、缓存使用、批量与循环
|
|
1255
|
+
|
|
1256
|
+
### 维度五:设计与架构(4 项)
|
|
1257
|
+
|
|
1258
|
+
职责划分、接口设计、扩展性、日志规范
|
|
1259
|
+
|
|
1260
|
+
### 维度六:规范与一致性(3 项)
|
|
1261
|
+
|
|
1262
|
+
编码规范、提交规范、配置管理
|
|
1263
|
+
|
|
1264
|
+
## 问题等级定义
|
|
1265
|
+
|
|
1266
|
+
| 等级 | 处理方式 |
|
|
1267
|
+
|------|---------|
|
|
1268
|
+
| **高危/严重** | 必须修复,阻塞合并 |
|
|
1269
|
+
| **中危** | 强烈建议修复,本轮处理 |
|
|
1270
|
+
| **一般** | 建议改进,记录跟踪 |
|
|
1271
|
+
| **低危/建议** | 供参考,酌情处理 |
|
|
1272
|
+
|
|
1273
|
+
## 评审结论判定规则
|
|
1274
|
+
|
|
1275
|
+
- **不通过**:存在任何高危/严重级别问题
|
|
1276
|
+
- **有条件通过**:存在中危级别问题,已确认修复计划
|
|
1277
|
+
- **通过**:仅有一般/建议级别问题或无问题
|
|
1278
|
+
SKILLEOF
|
|
1279
|
+
fi
|
|
1280
|
+
|
|
1281
|
+
if [ ! -f "$skills_dir/code-review/standards.md" ]; then
|
|
1282
|
+
cat > "$skills_dir/code-review/standards.md" << 'SKILLEOF'
|
|
1283
|
+
# 代码评审标准详细参考
|
|
1284
|
+
|
|
1285
|
+
## 维度一:正确性与功能
|
|
1286
|
+
|
|
1287
|
+
| # | 评审项 | 评审标准 | 等级 |
|
|
1288
|
+
|---|--------|---------|------|
|
|
1289
|
+
| 1.1 | 功能逻辑 | 代码实现与需求/设计文档一致,核心路径和分支路径均覆盖 | 严重 |
|
|
1290
|
+
| 1.2 | 边界与异常处理 | 空值、越界、并发、极端输入有合理处理 | 严重 |
|
|
1291
|
+
| 1.3 | 数据一致性 | 数据读写一致,事务使用正确,无竞态条件 | 严重 |
|
|
1292
|
+
| 1.4 | API 契约 | 接口入参/出参/错误码符合约定,向后兼容 | 严重 |
|
|
1293
|
+
| 1.5 | 测试覆盖 | 核心逻辑有对应的单元测试/集成测试,测试有效(非凑覆盖率) | 一般 |
|
|
1294
|
+
|
|
1295
|
+
---
|
|
1296
|
+
|
|
1297
|
+
## 维度二:安全性
|
|
1298
|
+
|
|
1299
|
+
### 2.1 业务数据篡改防护
|
|
1300
|
+
|
|
1301
|
+
| # | 评审项 | 等级 | 评审标准 |
|
|
1302
|
+
|---|--------|------|---------|
|
|
1303
|
+
| 2.1.1 | 必填项校验 | 高危 | 后端需校验是否接收到有效数值 |
|
|
1304
|
+
| 2.1.2 | 负值校验 | 高危 | 金额等字段需 >= 0 |
|
|
1305
|
+
| 2.1.3 | 一致性校验 | 中危 | 输入框前后端长度限制须保持一致 |
|
|
1306
|
+
| 2.1.4 | 选择框校验 | 高危 | 后端需校验入参是否在选择框可选范围内 |
|
|
1307
|
+
| 2.1.5 | 置灰项校验 | 中危 | 后端需对置灰项提交的值进行校验;更新类服务不允许修改置灰字段 |
|
|
1308
|
+
| 2.1.6 | 空值校验 | 高危 | 查询入参 ID 为空时需返回异常 |
|
|
1309
|
+
| 2.1.7 | 边界值校验 | 中危 | 分页等参数需限制最大值 |
|
|
1310
|
+
|
|
1311
|
+
### 2.2 未授权访问防护
|
|
1312
|
+
|
|
1313
|
+
| # | 评审项 | 等级 | 评审标准 |
|
|
1314
|
+
|---|--------|------|---------|
|
|
1315
|
+
| 2.2.1 | 登录校验 | 高危 | 所有服务使用登录过滤器拦截,校验 sessionId 是否有效 |
|
|
1316
|
+
| 2.2.2 | 权限校验 | 高危 | 未登录或无权限访问时,页面不可展示、接口无数据返回 |
|
|
1317
|
+
|
|
1318
|
+
### 2.3 越权防护
|
|
1319
|
+
|
|
1320
|
+
| # | 评审项 | 等级 | 评审标准 |
|
|
1321
|
+
|---|--------|------|---------|
|
|
1322
|
+
| 2.3.1 | 水平越权 | 高危 | ID 等参数修改后,返回数据须在当前账号权限范围内 |
|
|
1323
|
+
| 2.3.2 | ID 遍历风险 | 高危 | 禁止使用自增 ID,避免暴力遍历风险 |
|
|
1324
|
+
| 2.3.3 | 垂直越权 | 高危 | 接口需有权限校验,低权限账号调用高权限接口需返回异常 |
|
|
1325
|
+
|
|
1326
|
+
### 2.4 信息泄露防护
|
|
1327
|
+
|
|
1328
|
+
| # | 评审项 | 等级 | 评审标准 |
|
|
1329
|
+
|---|--------|------|---------|
|
|
1330
|
+
| 2.4.1 | 敏感数据脱敏 | 高危 | 敏感数据原则上不返回,需展示时脱敏返回 |
|
|
1331
|
+
| 2.4.2 | 组件版本号泄露 | 低危 | 避免 Nginx 等组件版本号泄露 |
|
|
1332
|
+
| 2.4.3 | 异常信息泄露 | 高危 | 禁止将 `e.getMessage()` 等异常信息返回前端 |
|
|
1333
|
+
| 2.4.4 | 密钥泄露 | 中危 | 地图 Key、OSS AccessKeyId 等禁止明文出现在 URL 中,必须加密传输 |
|
|
1334
|
+
|
|
1335
|
+
### 2.5 注入与攻击防护
|
|
1336
|
+
|
|
1337
|
+
| # | 评审项 | 等级 | 评审标准 |
|
|
1338
|
+
|---|--------|------|---------|
|
|
1339
|
+
| 2.5.1 | SQL 注入 | 高危 | 禁止字符串拼接 SQL;MyBatis 中禁止使用 `${}`,用 `#{}` 代替 |
|
|
1340
|
+
| 2.5.2 | CSRF 跨站请求伪造 | 中危 | 所有请求需添加 Referer/Origin 白名单校验 |
|
|
1341
|
+
| 2.5.3 | 会话固定攻击 | 中危 | 登录信息不缓存,需实时调用接口,与入口系统同步 |
|
|
1342
|
+
| 2.5.4 | URL 跳转 | 高危 | 跳转 URL 需做域名白名单限制 |
|
|
1343
|
+
| 2.5.5 | 用户名枚举 | 高危 | 统一登录异常返回,不区分"账号不存在"和"密码错误" |
|
|
1344
|
+
|
|
1345
|
+
### 2.6 前端安全
|
|
1346
|
+
|
|
1347
|
+
| # | 评审项 | 等级 | 评审标准 |
|
|
1348
|
+
|---|--------|------|---------|
|
|
1349
|
+
| 2.6.1 | 安全配置错误 | 低危 | 前端跳转统一加监听,登录失效时在解析页面前跳转登录页 |
|
|
1350
|
+
| 2.6.2 | 静态文件信息泄露 | 低危 | 调试 IP、注释 IP 及时删除,编译后 JS 中不得存在明文 IP |
|
|
1351
|
+
|
|
1352
|
+
---
|
|
1353
|
+
|
|
1354
|
+
## 维度三:可维护性
|
|
1355
|
+
|
|
1356
|
+
| # | 评审项 | 评审标准 | 等级 |
|
|
1357
|
+
|---|--------|---------|------|
|
|
1358
|
+
| 3.1 | 命名规范 | 变量、函数、类命名语义清晰,符合团队编码规范 | 一般 |
|
|
1359
|
+
| 3.2 | 方法/函数长度 | 单个方法不超过合理阈值(建议 50 行),职责单一 | 一般 |
|
|
1360
|
+
| 3.3 | 代码复杂度 | 嵌套层级不超过 3-4 层,圈复杂度合理 | 一般 |
|
|
1361
|
+
| 3.4 | 重复代码 | 无明显的复制粘贴代码,可复用逻辑已抽取 | 一般 |
|
|
1362
|
+
| 3.5 | 注释质量 | 关键业务逻辑有必要注释,无冗余/过时注释 | 一般 |
|
|
1363
|
+
| 3.6 | 依赖管理 | 新增依赖有必要性论证,无冗余/过期依赖 | 一般 |
|
|
1364
|
+
|
|
1365
|
+
---
|
|
1366
|
+
|
|
1367
|
+
## 维度四:性能
|
|
1368
|
+
|
|
1369
|
+
| # | 评审项 | 评审标准 | 等级 |
|
|
1370
|
+
|---|--------|---------|------|
|
|
1371
|
+
| 4.1 | 数据库查询 | 无 N+1 查询,大表查询有合理索引和分页 | 严重 |
|
|
1372
|
+
| 4.2 | 资源管理 | 连接、流、文件句柄等资源正确关闭,无泄露 | 严重 |
|
|
1373
|
+
| 4.3 | 缓存使用 | 热点数据有合理缓存策略,缓存击穿/雪崩有防护 | 一般 |
|
|
1374
|
+
| 4.4 | 批量与循环 | 循环内无重复计算/重复查询,批量操作使用批量接口 | 一般 |
|
|
1375
|
+
|
|
1376
|
+
---
|
|
1377
|
+
|
|
1378
|
+
## 维度五:设计与架构
|
|
1379
|
+
|
|
1380
|
+
| # | 评审项 | 评审标准 | 等级 |
|
|
1381
|
+
|---|--------|---------|------|
|
|
1382
|
+
| 5.1 | 职责划分 | 类/模块职责单一,不出现上帝类或功能堆砌 | 一般 |
|
|
1383
|
+
| 5.2 | 接口设计 | 接口粒度合理,遵循最小知识原则 | 一般 |
|
|
1384
|
+
| 5.3 | 扩展性 | 新功能不破坏现有结构,符合开闭原则 | 一般 |
|
|
1385
|
+
| 5.4 | 日志规范 | 关键操作有日志记录,日志级别使用恰当,不记录敏感信息 | 一般 |
|
|
1386
|
+
|
|
1387
|
+
---
|
|
1388
|
+
|
|
1389
|
+
## 维度六:规范与一致性
|
|
1390
|
+
|
|
1391
|
+
| # | 评审项 | 评审标准 | 等级 |
|
|
1392
|
+
|---|--------|---------|------|
|
|
1393
|
+
| 6.1 | 编码规范 | 缩进、命名、格式等符合团队编码规范 | 一般 |
|
|
1394
|
+
| 6.2 | 提交规范 | Commit 信息清晰,单次提交改动范围合理 | 一般 |
|
|
1395
|
+
| 6.3 | 配置管理 | 无硬编码配置值,敏感配置使用环境变量/配置中心 | 严重 |
|
|
1396
|
+
SKILLEOF
|
|
1397
|
+
fi
|
|
1398
|
+
|
|
1399
|
+
ok "skills 已创建"
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
# =====================================================================
|
|
1403
|
+
# 生成函数:memory 知识库
|
|
1404
|
+
# =====================================================================
|
|
1405
|
+
|
|
1406
|
+
generate_memory() {
|
|
1407
|
+
local target_dir="$1"
|
|
1408
|
+
local ptype="$2"
|
|
1409
|
+
local lang="$3"
|
|
1410
|
+
local backend="$4"
|
|
1411
|
+
local frontend="$5"
|
|
1412
|
+
local database="$6"
|
|
1413
|
+
local project_name="$7"
|
|
1414
|
+
local mode="$8" # "single" / "workspace" / "subproject"
|
|
1415
|
+
|
|
1416
|
+
local mem_dir="$target_dir/.claude/memory"
|
|
1417
|
+
mkdir -p "$mem_dir"
|
|
1418
|
+
|
|
1419
|
+
# architecture.md
|
|
1420
|
+
if [ ! -f "$mem_dir/architecture.md" ]; then
|
|
1421
|
+
if [ "$mode" = "workspace" ]; then
|
|
1422
|
+
local proj_table=""
|
|
1423
|
+
for proj in "${SUBPROJECTS[@]}"; do
|
|
1424
|
+
IFS='|' read -r path name ptype2 lang2 backend2 frontend2 database2 build2 category2 <<< "$proj"
|
|
1425
|
+
local tech_desc="$lang2"
|
|
1426
|
+
[ -n "$backend2" ] && tech_desc+=" + $backend2"
|
|
1427
|
+
[ -n "$frontend2" ] && tech_desc+=" + $frontend2"
|
|
1428
|
+
proj_table+="- **$name** ($path): $tech_desc, 数据库: ${database2:-待填写}\n"
|
|
1429
|
+
done
|
|
1430
|
+
cat > "$mem_dir/architecture.md" << EOF
|
|
1431
|
+
# 工作区架构文档
|
|
1432
|
+
|
|
1433
|
+
## 系统概述
|
|
1434
|
+
|
|
1435
|
+
$project_name 工作区,包含多个子项目。
|
|
1436
|
+
|
|
1437
|
+
## 子项目清单
|
|
1438
|
+
|
|
1439
|
+
$(echo -e "$proj_table")
|
|
1440
|
+
|
|
1441
|
+
## 架构关系
|
|
1442
|
+
|
|
1443
|
+
[待填写:子项目之间的调用关系、共享中间件、数据流向]
|
|
1444
|
+
|
|
1445
|
+
## 部署架构
|
|
1446
|
+
|
|
1447
|
+
[待填写:各子项目的部署方式、环境配置]
|
|
1448
|
+
|
|
1449
|
+
---
|
|
1450
|
+
|
|
1451
|
+
**最后更新:** $(date +%Y-%m-%d)
|
|
1452
|
+
EOF
|
|
1453
|
+
else
|
|
1454
|
+
# 构建技术栈详情
|
|
1455
|
+
local tech_details=""
|
|
1456
|
+
if [ -n "$lang" ]; then tech_details+=" - 语言:$lang\n"; fi
|
|
1457
|
+
if [ -n "$backend" ]; then tech_details+=" - 框架:$backend\n"; fi
|
|
1458
|
+
if [ -n "$frontend" ]; then tech_details+=" - 前端框架:$frontend\n"; fi
|
|
1459
|
+
if [ -n "$DET_BUILD" ]; then tech_details+=" - 构建工具:$DET_BUILD\n"; fi
|
|
1460
|
+
if [ -n "$DET_JAVA_VERSION" ]; then tech_details+=" - Java 版本:$DET_JAVA_VERSION\n"; fi
|
|
1461
|
+
if [ -n "$DET_SPRING_VERSION" ]; then tech_details+=" - Spring Boot 版本:$DET_SPRING_VERSION\n"; fi
|
|
1462
|
+
if [ -n "$DET_GO_VERSION" ]; then tech_details+=" - Go 版本:$DET_GO_VERSION\n"; fi
|
|
1463
|
+
if [ -n "$DET_PYTHON_VERSION" ]; then tech_details+=" - Python 版本:$DET_PYTHON_VERSION\n"; fi
|
|
1464
|
+
if [ -n "$database" ]; then tech_details+=" - 数据库:$database\n"; fi
|
|
1465
|
+
if [ -n "$DET_ORM" ]; then tech_details+=" - ORM:$DET_ORM\n"; fi
|
|
1466
|
+
if [ -n "$DET_CACHE" ]; then tech_details+=" - 缓存:$DET_CACHE\n"; fi
|
|
1467
|
+
if [ -n "$DET_MQ" ]; then tech_details+=" - 消息队列:$DET_MQ\n"; fi
|
|
1468
|
+
|
|
1469
|
+
local fe_details=""
|
|
1470
|
+
if [ -n "$DET_UI_LIB" ]; then fe_details+=" - UI 组件库:$DET_UI_LIB\n"; fi
|
|
1471
|
+
if [ -n "$DET_STATE_MGMT" ]; then fe_details+=" - 状态管理:$DET_STATE_MGMT\n"; fi
|
|
1472
|
+
if [ -n "$DET_CSS_FRAMEWORK" ]; then fe_details+=" - CSS 框架:$DET_CSS_FRAMEWORK\n"; fi
|
|
1473
|
+
if [ -n "$DET_LINT_TOOL" ]; then fe_details+=" - 代码检查:$DET_LINT_TOOL\n"; fi
|
|
1474
|
+
|
|
1475
|
+
local test_info=""
|
|
1476
|
+
if [ -n "$DET_TEST_FRAMEWORK" ]; then test_info=" - 测试框架:$DET_TEST_FRAMEWORK\n"; fi
|
|
1477
|
+
if [ -n "$DET_API_DOC" ]; then test_info+=" - API 文档:$DET_API_DOC\n"; fi
|
|
1478
|
+
|
|
1479
|
+
local dir_tree="${DET_DIR_TREE:-$(find "$target_dir" -maxdepth 3 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/target/*' -not -path '*/__pycache__/*' -not -path '*/.claude/*' 2>/dev/null | head -50 | sort)}"
|
|
1480
|
+
|
|
1481
|
+
cat > "$mem_dir/architecture.md" << EOF
|
|
1482
|
+
# 项目架构文档
|
|
1483
|
+
|
|
1484
|
+
## 系统概述
|
|
1485
|
+
|
|
1486
|
+
$project_name 项目
|
|
1487
|
+
|
|
1488
|
+
## 技术栈
|
|
1489
|
+
|
|
1490
|
+
$(if [ -n "$tech_details" ]; then echo -e "$tech_details"; else echo "[待填写]"; fi)
|
|
1491
|
+
$(if [ -n "$fe_details" ]; then echo -e "### 前端工具链\n$fe_details"; fi)
|
|
1492
|
+
$(if [ -n "$test_info" ]; then echo -e "### 开发工具\n$test_info"; fi)
|
|
1493
|
+
|
|
1494
|
+
## 目录结构
|
|
1495
|
+
|
|
1496
|
+
$(echo "$dir_tree" | sed 's/^/ /')
|
|
1497
|
+
|
|
1498
|
+
---
|
|
1499
|
+
|
|
1500
|
+
**最后更新:** $(date +%Y-%m-%d)
|
|
1501
|
+
EOF
|
|
1502
|
+
fi
|
|
1503
|
+
fi
|
|
1504
|
+
|
|
1505
|
+
# frontend-standards.md — 前端子项目或单项目
|
|
1506
|
+
if [ "$mode" != "workspace" ] && [ -n "$frontend" ] && [ ! -f "$mem_dir/frontend-standards.md" ]; then
|
|
1507
|
+
local fe_tool_info=""
|
|
1508
|
+
if [ -n "$DET_UI_LIB" ]; then fe_tool_info+="- UI 组件库:$DET_UI_LIB\n"; fi
|
|
1509
|
+
if [ -n "$DET_STATE_MGMT" ]; then fe_tool_info+="- 状态管理:$DET_STATE_MGMT\n"; fi
|
|
1510
|
+
if [ -n "$DET_CSS_FRAMEWORK" ]; then fe_tool_info+="- CSS 框架:$DET_CSS_FRAMEWORK\n"; fi
|
|
1511
|
+
if [ -n "$DET_LINT_TOOL" ]; then fe_tool_info+="- 代码检查:$DET_LINT_TOOL\n"; fi
|
|
1512
|
+
if [ -n "$DET_TEST_FRAMEWORK" ]; then fe_tool_info+="- 测试框架:$DET_TEST_FRAMEWORK\n"; fi
|
|
1513
|
+
|
|
1514
|
+
cat > "$mem_dir/frontend-standards.md" << EOF
|
|
1515
|
+
# 前端开发规范
|
|
1516
|
+
|
|
1517
|
+
## 技术工具链
|
|
1518
|
+
|
|
1519
|
+
$(if [ -n "$fe_tool_info" ]; then echo -e "$fe_tool_info"; else echo "[待填写]"; fi)
|
|
1520
|
+
|
|
1521
|
+
## 组件规范
|
|
1522
|
+
- 组件文件名:PascalCase(如 UserList.vue / UserList.tsx)
|
|
1523
|
+
- 组件内变量:camelCase
|
|
1524
|
+
- 常量:UPPER_SNAKE_CASE
|
|
1525
|
+
|
|
1526
|
+
## 样式规范
|
|
1527
|
+
- 使用 BEM 命名规范或 Scoped CSS
|
|
1528
|
+
- 响应式断点:768px / 1024px
|
|
1529
|
+
|
|
1530
|
+
## API 调用规范
|
|
1531
|
+
- 统一通过 api/ 目录下的模块调用
|
|
1532
|
+
- 统一错误处理
|
|
1533
|
+
|
|
1534
|
+
---
|
|
1535
|
+
|
|
1536
|
+
**最后更新:** $(date +%Y-%m-%d)
|
|
1537
|
+
EOF
|
|
1538
|
+
fi
|
|
1539
|
+
|
|
1540
|
+
# backend-standards.md — 后端子项目或单项目
|
|
1541
|
+
if [ "$mode" != "workspace" ] && [ -n "$backend" ] && [ ! -f "$mem_dir/backend-standards.md" ]; then
|
|
1542
|
+
local layer_desc=""
|
|
1543
|
+
if echo "$ptype" | grep -q "java"; then
|
|
1544
|
+
layer_desc="- Controller 层:接收请求、参数校验
|
|
1545
|
+
- Service 层:业务逻辑
|
|
1546
|
+
- Mapper/DAO 层:数据访问"
|
|
1547
|
+
elif echo "$ptype" | grep -q "go"; then
|
|
1548
|
+
layer_desc="- Handler 层:接收请求
|
|
1549
|
+
- Service 层:业务逻辑
|
|
1550
|
+
- Repository 层:数据访问"
|
|
1551
|
+
elif echo "$ptype" | grep -q "python"; then
|
|
1552
|
+
layer_desc="- Router 层:路由定义
|
|
1553
|
+
- Service 层:业务逻辑
|
|
1554
|
+
- Model 层:数据模型"
|
|
1555
|
+
else
|
|
1556
|
+
layer_desc="- 接口层:接收请求
|
|
1557
|
+
- 业务层:业务逻辑
|
|
1558
|
+
- 数据层:数据访问"
|
|
1559
|
+
fi
|
|
1560
|
+
|
|
1561
|
+
local be_tool_info=""
|
|
1562
|
+
if [ -n "$DET_ORM" ]; then be_tool_info+="- ORM:$DET_ORM\n"; fi
|
|
1563
|
+
if [ -n "$DET_TEST_FRAMEWORK" ]; then be_tool_info+="- 测试框架:$DET_TEST_FRAMEWORK\n"; fi
|
|
1564
|
+
if [ -n "$DET_API_DOC" ]; then be_tool_info+="- API 文档:$DET_API_DOC\n"; fi
|
|
1565
|
+
if [ -n "$DET_CACHE" ]; then be_tool_info+="- 缓存:$DET_CACHE\n"; fi
|
|
1566
|
+
if [ -n "$DET_MQ" ]; then be_tool_info+="- 消息队列:$DET_MQ\n"; fi
|
|
1567
|
+
|
|
1568
|
+
cat > "$mem_dir/backend-standards.md" << EOF
|
|
1569
|
+
# 后端开发规范
|
|
1570
|
+
|
|
1571
|
+
## 技术工具链
|
|
1572
|
+
|
|
1573
|
+
$(if [ -n "$be_tool_info" ]; then echo -e "$be_tool_info"; else echo "[待填写]"; fi)
|
|
1574
|
+
|
|
1575
|
+
## API 设计规范
|
|
1576
|
+
- RESTful 风格
|
|
1577
|
+
- 统一响应格式:{ code, message, data, timestamp }
|
|
1578
|
+
|
|
1579
|
+
## 代码分层规范
|
|
1580
|
+
|
|
1581
|
+
$layer_desc
|
|
1582
|
+
|
|
1583
|
+
## 数据库规范
|
|
1584
|
+
- 表名:小写 + 下划线(如 user_profile)
|
|
1585
|
+
- 必备字段:id, created_at, updated_at
|
|
1586
|
+
|
|
1587
|
+
## 异常处理
|
|
1588
|
+
- 统一异常处理机制
|
|
1589
|
+
- 日志规范:ERROR / WARN / INFO / DEBUG
|
|
1590
|
+
|
|
1591
|
+
---
|
|
1592
|
+
|
|
1593
|
+
**最后更新:** $(date +%Y-%m-%d)
|
|
1594
|
+
EOF
|
|
1595
|
+
fi
|
|
1596
|
+
|
|
1597
|
+
# business-logic.md — 非工作区级别
|
|
1598
|
+
if [ "$mode" != "workspace" ] && [ ! -f "$mem_dir/business-logic.md" ]; then
|
|
1599
|
+
cat > "$mem_dir/business-logic.md" << 'EOF'
|
|
1600
|
+
# 业务逻辑说明
|
|
1601
|
+
|
|
1602
|
+
## 核心业务流程
|
|
1603
|
+
|
|
1604
|
+
[待填写:描述主要业务流程]
|
|
1605
|
+
|
|
1606
|
+
## 数据流向
|
|
1607
|
+
|
|
1608
|
+
前端页面 → API → Controller → Service → DAO → 数据库
|
|
1609
|
+
|
|
1610
|
+
## 权限控制
|
|
1611
|
+
|
|
1612
|
+
[待填写:角色和权限矩阵]
|
|
1613
|
+
|
|
1614
|
+
---
|
|
1615
|
+
|
|
1616
|
+
**最后更新:** 待填写
|
|
1617
|
+
EOF
|
|
1618
|
+
fi
|
|
1619
|
+
|
|
1620
|
+
# shared memory files for all modes
|
|
1621
|
+
if [ ! -f "$mem_dir/superpowers-config.md" ]; then
|
|
1622
|
+
cat > "$mem_dir/superpowers-config.md" << 'EOF'
|
|
1623
|
+
# Superpowers 配置
|
|
1624
|
+
|
|
1625
|
+
## Skill 启用状态
|
|
1626
|
+
|
|
1627
|
+
| 阶段 | Skill | 状态 | 说明 |
|
|
1628
|
+
|------|-------|------|------|
|
|
1629
|
+
| 入口 | using-superpowers | enabled | 自动判断流程 |
|
|
1630
|
+
| 设计 | brainstorming | conditional | 中等+复杂 |
|
|
1631
|
+
| 规划 | writing-plans | conditional | 复杂任务 |
|
|
1632
|
+
| 隔离 | using-git-worktrees | conditional | 复杂任务 |
|
|
1633
|
+
| 执行 | subagent-driven-development | conditional | 复杂任务 |
|
|
1634
|
+
| 测试 | test-driven-development | conditional | 中等+复杂 |
|
|
1635
|
+
| 调试 | systematic-debugging | enabled | 遇到 bug 自动触发 |
|
|
1636
|
+
| 审查 | requesting/receiving-code-review | conditional | 复杂任务 |
|
|
1637
|
+
| 验证 | verification-before-completion | enabled | 完成前必验证 |
|
|
1638
|
+
| 收尾 | finishing-a-development-branch | conditional | 中等+复杂 |
|
|
1639
|
+
|
|
1640
|
+
## 配置值
|
|
1641
|
+
|
|
1642
|
+
- enabled: 始终执行
|
|
1643
|
+
- disabled: 始终跳过
|
|
1644
|
+
- conditional: 按复杂度判断
|
|
1645
|
+
- manual: 用户明确调用
|
|
1646
|
+
EOF
|
|
1647
|
+
fi
|
|
1648
|
+
|
|
1649
|
+
if [ ! -f "$mem_dir/learned-lessons.md" ]; then
|
|
1650
|
+
cat > "$mem_dir/learned-lessons.md" << 'EOF'
|
|
1651
|
+
# 错误驱动的知识积累
|
|
1652
|
+
|
|
1653
|
+
> 每一条规则对应一个过去 AI 犯过的错误。Agent 犯错 → 加一条规则 → 以后不再犯同类错误。
|
|
1654
|
+
|
|
1655
|
+
## 编码错误
|
|
1656
|
+
|
|
1657
|
+
[待积累]
|
|
1658
|
+
|
|
1659
|
+
## 流程错误
|
|
1660
|
+
|
|
1661
|
+
[待积累]
|
|
1662
|
+
|
|
1663
|
+
## 架构错误
|
|
1664
|
+
|
|
1665
|
+
[待积累]
|
|
1666
|
+
|
|
1667
|
+
---
|
|
1668
|
+
|
|
1669
|
+
## 记录规则
|
|
1670
|
+
|
|
1671
|
+
- **触发条件:** AI 犯了一个新的、有代表性的错误(非偶然失误)
|
|
1672
|
+
- **记录内容:** 错误现象 + 根因 + 规避规则 + 日期
|
|
1673
|
+
- **后续动作:** 编码层面 → 更新 rules/;流程层面 → 更新 workflow 步骤
|
|
1674
|
+
EOF
|
|
1675
|
+
fi
|
|
1676
|
+
|
|
1677
|
+
if [ ! -f "$mem_dir/issues.md" ]; then
|
|
1678
|
+
cat > "$mem_dir/issues.md" << 'EOF'
|
|
1679
|
+
# 问题记录
|
|
1680
|
+
|
|
1681
|
+
## 已解决问题
|
|
1682
|
+
|
|
1683
|
+
[待积累]
|
|
1684
|
+
|
|
1685
|
+
## 待解决问题
|
|
1686
|
+
|
|
1687
|
+
[待积累]
|
|
1688
|
+
|
|
1689
|
+
## 技术债务
|
|
1690
|
+
|
|
1691
|
+
[待积累]
|
|
1692
|
+
|
|
1693
|
+
---
|
|
1694
|
+
|
|
1695
|
+
**最后更新:** 待填写
|
|
1696
|
+
EOF
|
|
1697
|
+
fi
|
|
1698
|
+
|
|
1699
|
+
ok "memory 知识库已创建"
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
# =====================================================================
|
|
1703
|
+
# 生成函数:MEMORY.md 索引
|
|
1704
|
+
# =====================================================================
|
|
1705
|
+
|
|
1706
|
+
generate_memory_index() {
|
|
1707
|
+
local target_dir="$1"
|
|
1708
|
+
local mode="$2"
|
|
1709
|
+
|
|
1710
|
+
if [ ! -f "$target_dir/.claude/MEMORY.md" ]; then
|
|
1711
|
+
if [ "$mode" = "workspace" ]; then
|
|
1712
|
+
cat > "$target_dir/.claude/MEMORY.md" << EOF
|
|
1713
|
+
# 工作区知识库索引
|
|
1714
|
+
|
|
1715
|
+
## 工作区文档
|
|
1716
|
+
|
|
1717
|
+
- [工作区架构](memory/architecture.md) - 子项目清单和架构关系
|
|
1718
|
+
- [Superpowers 配置](memory/superpowers-config.md) - Superpowers Skill 启用状态
|
|
1719
|
+
- [错误积累](memory/learned-lessons.md) - AI 常犯错误和规避规则
|
|
1720
|
+
- [问题记录](memory/issues.md) - 已解决和待解决问题
|
|
1721
|
+
|
|
1722
|
+
## 子项目文档
|
|
1723
|
+
|
|
1724
|
+
各子项目有独立的 memory/ 目录,cd 到对应子项目后可查看。
|
|
1725
|
+
|
|
1726
|
+
## 快速开始
|
|
1727
|
+
|
|
1728
|
+
1. 在工作区根目录:查看全局架构和规范
|
|
1729
|
+
2. cd 到子项目:查看项目专属规范和业务逻辑
|
|
1730
|
+
3. 跨项目开发:使用 \`/fullstack\` 协调
|
|
1731
|
+
|
|
1732
|
+
## 更新日志
|
|
1733
|
+
|
|
1734
|
+
- $(date +%Y-%m-%d): 初始化工作区知识库
|
|
1735
|
+
EOF
|
|
1736
|
+
else
|
|
1737
|
+
cat > "$target_dir/.claude/MEMORY.md" << EOF
|
|
1738
|
+
# 项目知识库索引
|
|
1739
|
+
|
|
1740
|
+
## 核心文档
|
|
1741
|
+
|
|
1742
|
+
- [项目架构](memory/architecture.md) - 系统架构和技术选型
|
|
1743
|
+
- [前端规范](memory/frontend-standards.md) - 前端开发规范
|
|
1744
|
+
- [后端规范](memory/backend-standards.md) - 后端开发规范和 API 设计标准
|
|
1745
|
+
- [业务逻辑](memory/business-logic.md) - 核心业务流程和规则
|
|
1746
|
+
- [Superpowers 配置](memory/superpowers-config.md) - Superpowers Skill 启用状态
|
|
1747
|
+
- [错误积累](memory/learned-lessons.md) - AI 常犯错误和规避规则
|
|
1748
|
+
- [问题记录](memory/issues.md) - 已解决和待解决问题
|
|
1749
|
+
|
|
1750
|
+
## 快速开始
|
|
1751
|
+
|
|
1752
|
+
1. 新成员:读 architecture.md → 读对应规范 → 读 business-logic.md
|
|
1753
|
+
2. AI 助手:前端优先看 frontend-standards.md,后端优先看 backend-standards.md
|
|
1754
|
+
3. Superpowers 配置:见 memory/superpowers-config.md
|
|
1755
|
+
|
|
1756
|
+
## 更新日志
|
|
1757
|
+
|
|
1758
|
+
- $(date +%Y-%m-%d): 初始化知识库
|
|
1759
|
+
EOF
|
|
1760
|
+
fi
|
|
1761
|
+
fi
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
# =====================================================================
|
|
1765
|
+
# 生成函数:辅助脚本
|
|
1766
|
+
# =====================================================================
|
|
1767
|
+
# 生成函数:流程定义文件
|
|
1768
|
+
# =====================================================================
|
|
1769
|
+
|
|
1770
|
+
generate_workflow() {
|
|
1771
|
+
local target_dir="$1"
|
|
1772
|
+
local workflow_dir="$target_dir/.claude/workflow"
|
|
1773
|
+
|
|
1774
|
+
mkdir -p "$workflow_dir"
|
|
1775
|
+
|
|
1776
|
+
if [ ! -f "$workflow_dir/WORKFLOW-GUIDE.md" ]; then
|
|
1777
|
+
cat > "$workflow_dir/WORKFLOW-GUIDE.md" << 'WORKFLOWEOF'
|
|
1778
|
+
# 流程定义指南
|
|
1779
|
+
|
|
1780
|
+
本文件定义了各工作流的标准阶段、角色分工、输入输出和流转规则。
|
|
1781
|
+
|
|
1782
|
+
## 后端标准流程
|
|
1783
|
+
|
|
1784
|
+
| 阶段 | 触发 Skill | 输入 | 输出 | 前进条件 | 可回退到 |
|
|
1785
|
+
|------|-----------|------|------|---------|---------|
|
|
1786
|
+
| 需求入口 | using-superpowers | 用户描述 | 复杂度判断 | 自动判定 | - |
|
|
1787
|
+
| 需求澄清 | brainstorming | 复杂度 ≥ 中等 | specs/active/*.md | 用户确认 spec | 需求入口 |
|
|
1788
|
+
| 方案设计 | writing-plans | 复杂度 = 复杂 | 任务计划 | 用户确认 | 需求澄清 |
|
|
1789
|
+
| 实现 | executing-plans | spec + 计划 | DAO → Service → Controller | 构建+测试通过 | 方案设计 |
|
|
1790
|
+
| 代码评审 | code-review | 复杂度 ≥ 中等 | 评审报告 | 无高危问题 | 实现 |
|
|
1791
|
+
| 收尾 | finishing-branch | 验证通过 | spec 归档 | - | - |
|
|
1792
|
+
|
|
1793
|
+
## 通用规则
|
|
1794
|
+
|
|
1795
|
+
1. 下游不能修改上游产出(实现不能改 spec,只能打回)
|
|
1796
|
+
2. 每个阶段必须有明确的"完成"定义
|
|
1797
|
+
3. 连续 3 次回退到同一阶段,暂停由人决策
|
|
1798
|
+
4. 验证是硬门禁 — 构建失败、测试失败、评审有高危,必须回退
|
|
1799
|
+
5. spec 是唯一真相来源 — AI 从文件读约束,不靠聊天记录
|
|
1800
|
+
WORKFLOWEOF
|
|
1801
|
+
ok "生成 workflow/WORKFLOW-GUIDE.md"
|
|
1802
|
+
fi
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
# =====================================================================
|
|
1806
|
+
|
|
1807
|
+
generate_scripts() {
|
|
1808
|
+
local target_dir="$1"
|
|
1809
|
+
local scripts_dir="$target_dir/.claude/scripts"
|
|
1810
|
+
mkdir -p "$scripts_dir"
|
|
1811
|
+
|
|
1812
|
+
ok "scripts 已创建"
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
# =====================================================================
|
|
1816
|
+
# 生成函数:CLAUDE.md
|
|
1817
|
+
# =====================================================================
|
|
1818
|
+
|
|
1819
|
+
generate_claude_md_single() {
|
|
1820
|
+
local target_dir="$1"
|
|
1821
|
+
local ptype="$2"
|
|
1822
|
+
local lang="$3"
|
|
1823
|
+
local backend="$4"
|
|
1824
|
+
local frontend="$5"
|
|
1825
|
+
local database="$6"
|
|
1826
|
+
|
|
1827
|
+
if [ -f "$target_dir/CLAUDE.md" ]; then
|
|
1828
|
+
info "CLAUDE.md 已存在,跳过"
|
|
1829
|
+
return
|
|
1830
|
+
fi
|
|
1831
|
+
|
|
1832
|
+
cat > "$target_dir/CLAUDE.md" << CLAUDEEOF
|
|
1833
|
+
# CLAUDE.md
|
|
1834
|
+
|
|
1835
|
+
## 技术栈
|
|
1836
|
+
|
|
1837
|
+
- 前端:${frontend:-待填写}
|
|
1838
|
+
- 后端:${lang:-待填写} + ${backend:-待填写}
|
|
1839
|
+
- 数据库:${database:-待填写}
|
|
1840
|
+
|
|
1841
|
+
## 核心原则:原生优先
|
|
1842
|
+
|
|
1843
|
+
简单任务(改变量、修 bug、写工具函数)直接说需求,不走 workflow。
|
|
1844
|
+
复杂任务(新功能模块、多文件变更)才上 workflow 和 Spec。
|
|
1845
|
+
|
|
1846
|
+
> 90% 的场景用原生 Claude Code 就够了。过度工程化是最大的浪费。
|
|
1847
|
+
|
|
1848
|
+
## 开发铁律
|
|
1849
|
+
|
|
1850
|
+
1. **没设计不写代码** — 动手前先确认文件、范围、方案
|
|
1851
|
+
2. **没测试不写代码** — 先写失败测试,再写实现
|
|
1852
|
+
3. **没验证不说完成** — 必须运行验证命令并贴出结果
|
|
1853
|
+
|
|
1854
|
+
## 模式切换
|
|
1855
|
+
|
|
1856
|
+
| 命令 | 用途 |
|
|
1857
|
+
|------|------|
|
|
1858
|
+
| \`/frontend\` | 前端开发 |
|
|
1859
|
+
| \`/backend\` | 后端开发 |
|
|
1860
|
+
| \`/fullstack\` | 全栈协调 |
|
|
1861
|
+
|
|
1862
|
+
## 核心约束
|
|
1863
|
+
|
|
1864
|
+
- 后端分层:Controller → Service → DAO,禁止跨层
|
|
1865
|
+
- 前端 API 调用走 \`api/\` 模块
|
|
1866
|
+
- RESTful 统一响应:\`{ code, message, data, timestamp }\`
|
|
1867
|
+
- 所有外部输入必须校验,不引入安全漏洞
|
|
1868
|
+
|
|
1869
|
+
## 文档地图
|
|
1870
|
+
|
|
1871
|
+
| 目录 | 用途 | 何时读 |
|
|
1872
|
+
|------|------|--------|
|
|
1873
|
+
| \`.claude/rules/\` | 自动触发的编码规则 | 编辑代码时自动生效 |
|
|
1874
|
+
| \`.claude/skills/\` | 完整工作流编排 | 走 workflow 时按需加载 |
|
|
1875
|
+
| \`.claude/memory/\` | 项目知识库(架构、规范、业务) | 需要项目上下文时引用 |
|
|
1876
|
+
| \`.claude/specs/\` | 功能规格文档 | 中等+复杂任务时创建和引用 |
|
|
1877
|
+
| \`.claude/scripts/\` | 初始化和验证脚本 | 新项目接入时使用 |
|
|
1878
|
+
|
|
1879
|
+
## 复杂度分级
|
|
1880
|
+
|
|
1881
|
+
| 级别 | 定义 | 策略 |
|
|
1882
|
+
|------|------|------|
|
|
1883
|
+
| 简单 | 单文件修改,< 30 分钟 | 原生,不走 workflow |
|
|
1884
|
+
| 中等 | 新组件/新接口,30 分钟 - 2 小时 | brainstorming + spec + TDD |
|
|
1885
|
+
| 复杂 | 新功能模块,> 2 小时 | 完整 workflow + spec + worktree + review |
|
|
1886
|
+
CLAUDEEOF
|
|
1887
|
+
ok "CLAUDE.md 已创建"
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
generate_claude_md_workspace() {
|
|
1891
|
+
local target_dir="$1"
|
|
1892
|
+
|
|
1893
|
+
if [ -f "$target_dir/CLAUDE.md" ]; then
|
|
1894
|
+
info "CLAUDE.md 已存在,跳过"
|
|
1895
|
+
return
|
|
1896
|
+
fi
|
|
1897
|
+
|
|
1898
|
+
# 构建子项目表格
|
|
1899
|
+
local proj_table=""
|
|
1900
|
+
for proj in "${SUBPROJECTS[@]}"; do
|
|
1901
|
+
IFS='|' read -r path name ptype lang backend frontend database build category <<< "$proj"
|
|
1902
|
+
local tech_desc="${lang}"
|
|
1903
|
+
local framework=""
|
|
1904
|
+
[ -n "$backend" ] && framework="$backend"
|
|
1905
|
+
[ -n "$frontend" ] && framework="${framework:+$framework / }$frontend"
|
|
1906
|
+
proj_table+="| $name | \`$path\` | $tech_desc + $framework | $category |\n"
|
|
1907
|
+
done
|
|
1908
|
+
|
|
1909
|
+
cat > "$target_dir/CLAUDE.md" << CLAUDEEOF
|
|
1910
|
+
# CLAUDE.md — 工作区
|
|
1911
|
+
|
|
1912
|
+
## 工作区概览
|
|
1913
|
+
|
|
1914
|
+
本工作区包含多个子项目:
|
|
1915
|
+
|
|
1916
|
+
| 子项目 | 路径 | 技术栈 | 类型 |
|
|
1917
|
+
|--------|------|--------|------|
|
|
1918
|
+
$(echo -e "$proj_table")
|
|
1919
|
+
|
|
1920
|
+
## 核心原则:原生优先
|
|
1921
|
+
|
|
1922
|
+
简单任务(改变量、修 bug、写工具函数)直接说需求,不走 workflow。
|
|
1923
|
+
复杂任务(新功能模块、多文件变更)才上 workflow 和 Spec。
|
|
1924
|
+
|
|
1925
|
+
> 90% 的场景用原生 Claude Code 就够了。过度工程化是最大的浪费。
|
|
1926
|
+
|
|
1927
|
+
## 开发铁律
|
|
1928
|
+
|
|
1929
|
+
1. **没设计不写代码** — 动手前先确认文件、范围、方案
|
|
1930
|
+
2. **没测试不写代码** — 先写失败测试,再写实现
|
|
1931
|
+
3. **没验证不说完成** — 必须运行验证命令并贴出结果
|
|
1932
|
+
|
|
1933
|
+
## 工作方式
|
|
1934
|
+
|
|
1935
|
+
- **单项目开发**: \`cd <子项目目录>\` 后直接说需求,加载该项目的专属配置
|
|
1936
|
+
- **跨项目开发**: 在工作区根目录使用 \`/fullstack\` 协调
|
|
1937
|
+
- 每个子项目有自己的 \`.claude/rules/\` 和 \`.claude/memory/\`
|
|
1938
|
+
|
|
1939
|
+
## 模式切换
|
|
1940
|
+
|
|
1941
|
+
| 命令 | 用途 |
|
|
1942
|
+
|------|------|
|
|
1943
|
+
| \`/frontend\` | 前端开发(显示前端子项目列表) |
|
|
1944
|
+
| \`/backend\` | 后端开发(显示后端子项目列表) |
|
|
1945
|
+
| \`/fullstack\` | 全栈协调 |
|
|
1946
|
+
|
|
1947
|
+
## 文档地图
|
|
1948
|
+
|
|
1949
|
+
| 目录 | 用途 | 何时读 |
|
|
1950
|
+
|------|------|--------|
|
|
1951
|
+
| \`.claude/rules/\` | 工作区级共享规则 | 全局生效 |
|
|
1952
|
+
| \`.claude/commands/\` | 工作区级共享命令 | 全局可用 |
|
|
1953
|
+
| \`.claude/memory/\` | 工作区级知识库 | 全局架构 |
|
|
1954
|
+
| \`<子项目>/.claude/\` | 子项目专属配置 | cd 到子项目时生效 |
|
|
1955
|
+
|
|
1956
|
+
## 复杂度分级
|
|
1957
|
+
|
|
1958
|
+
| 级别 | 定义 | 策略 |
|
|
1959
|
+
|------|------|------|
|
|
1960
|
+
| 简单 | 单文件修改,< 30 分钟 | 原生,不走 workflow |
|
|
1961
|
+
| 中等 | 新组件/新接口,30 分钟 - 2 小时 | brainstorming + spec + TDD |
|
|
1962
|
+
| 复杂 | 新功能模块,> 2 小时 | 完整 workflow + spec + worktree + review |
|
|
1963
|
+
CLAUDEEOF
|
|
1964
|
+
ok "工作区 CLAUDE.md 已创建"
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
generate_claude_md_subproject() {
|
|
1968
|
+
local target_dir="$1"
|
|
1969
|
+
local proj_name="$2"
|
|
1970
|
+
local lang="$3"
|
|
1971
|
+
local backend="$4"
|
|
1972
|
+
local frontend="$5"
|
|
1973
|
+
local database="$6"
|
|
1974
|
+
|
|
1975
|
+
if [ -f "$target_dir/CLAUDE.md" ]; then
|
|
1976
|
+
info "子项目 $proj_name 的 CLAUDE.md 已存在,跳过"
|
|
1977
|
+
return
|
|
1978
|
+
fi
|
|
1979
|
+
|
|
1980
|
+
cat > "$target_dir/CLAUDE.md" << CLAUDEEOF
|
|
1981
|
+
# CLAUDE.md — $proj_name
|
|
1982
|
+
|
|
1983
|
+
## 技术栈
|
|
1984
|
+
|
|
1985
|
+
- 语言:${lang}
|
|
1986
|
+
- 框架:${backend}${frontend:+ / }${frontend}
|
|
1987
|
+
- 数据库:${database:-待填写}
|
|
1988
|
+
|
|
1989
|
+
## 本项目规范
|
|
1990
|
+
|
|
1991
|
+
- 详见 \`.claude/rules/\` 下的技术栈专属规则
|
|
1992
|
+
- 详见 \`.claude/memory/\` 下的项目知识库
|
|
1993
|
+
|
|
1994
|
+
## 核心约束
|
|
1995
|
+
|
|
1996
|
+
- 严格分层,禁止跨层调用
|
|
1997
|
+
- 统一响应格式:\`{ code, message, data, timestamp }\`
|
|
1998
|
+
- 所有外部输入必须校验,不引入安全漏洞
|
|
1999
|
+
|
|
2000
|
+
## 所属工作区
|
|
2001
|
+
|
|
2002
|
+
- 本项目属于上层工作区,全局配置见上层 \`.claude/\`
|
|
2003
|
+
CLAUDEEOF
|
|
2004
|
+
ok "子项目 $proj_name CLAUDE.md 已创建"
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
# =====================================================================
|
|
2008
|
+
# 生成函数:README
|
|
2009
|
+
# =====================================================================
|
|
2010
|
+
|
|
2011
|
+
generate_readme() {
|
|
2012
|
+
local target_dir="$1"
|
|
2013
|
+
local mode="$2"
|
|
2014
|
+
local ptype="$3"
|
|
2015
|
+
local lang="$4"
|
|
2016
|
+
|
|
2017
|
+
if [ -f "$target_dir/.claude/README.md" ]; then
|
|
2018
|
+
return
|
|
2019
|
+
fi
|
|
2020
|
+
|
|
2021
|
+
cat > "$target_dir/.claude/README.md" << EOF
|
|
2022
|
+
# Claude Code AI 辅助开发配置
|
|
2023
|
+
|
|
2024
|
+
## 模式
|
|
2025
|
+
$([ "$mode" = "workspace" ] && echo "工作区模式(多项目)" || echo "单项目模式")
|
|
2026
|
+
|
|
2027
|
+
## 项目信息
|
|
2028
|
+
- 名称:${WORKSPACE_NAME}
|
|
2029
|
+
- 类型:${ptype:-generic}
|
|
2030
|
+
- 语言:${lang:-通用}
|
|
2031
|
+
|
|
2032
|
+
## 架构说明
|
|
2033
|
+
|
|
2034
|
+
| 目录 | 用途 | 触发方式 |
|
|
2035
|
+
|------|------|----------|
|
|
2036
|
+
| \`CLAUDE.md\` | 项目最高优先级指令 | 自动加载 |
|
|
2037
|
+
| \`commands/\` | 斜杠命令(模式切换) | 用户输入 \`/\` 前缀 |
|
|
2038
|
+
| \`rules/\` | 条件规则(自动触发) | 编辑代码时自动生效 |
|
|
2039
|
+
| \`skills/\` | 工作流技能 | 用户 \`/skill-name\` 调用 |
|
|
2040
|
+
| \`memory/\` | 项目知识库 | 被规则和命令引用 |
|
|
2041
|
+
|
|
2042
|
+
$([ "$mode" = "workspace" ] && echo "各子项目有自己的 \`.claude/\` 目录,cd 到子项目后自动加载专属配置。" || echo "")
|
|
2043
|
+
|
|
2044
|
+
## 使用方式
|
|
2045
|
+
|
|
2046
|
+
| 命令 | 说明 |
|
|
2047
|
+
|------|------|
|
|
2048
|
+
| \`/frontend\` | 前端开发模式 |
|
|
2049
|
+
| \`/backend\` | 后端开发模式 |
|
|
2050
|
+
| \`/fullstack\` | 全栈协调模式 |
|
|
2051
|
+
|
|
2052
|
+
## 验证配置
|
|
2053
|
+
|
|
2054
|
+
\`\`\`bash
|
|
2055
|
+
apprentice doctor
|
|
2056
|
+
\`\`\`
|
|
2057
|
+
|
|
2058
|
+
---
|
|
2059
|
+
|
|
2060
|
+
**初始化日期:** $(date +%Y-%m-%d)
|
|
2061
|
+
EOF
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
# =====================================================================
|
|
2065
|
+
# 生成函数:spec 目录和指南
|
|
2066
|
+
# =====================================================================
|
|
2067
|
+
|
|
2068
|
+
generate_spec_structure() {
|
|
2069
|
+
local target_dir="$1"
|
|
2070
|
+
mkdir -p "$target_dir/.claude/specs/active"
|
|
2071
|
+
mkdir -p "$target_dir/.claude/specs/archived"
|
|
2072
|
+
mkdir -p "$target_dir/.claude/reports"
|
|
2073
|
+
|
|
2074
|
+
if [ ! -f "$target_dir/.claude/specs/SPEC-GUIDE.md" ]; then
|
|
2075
|
+
cat > "$target_dir/.claude/specs/SPEC-GUIDE.md" << 'EOF'
|
|
2076
|
+
# Spec 使用指南
|
|
2077
|
+
|
|
2078
|
+
## 生命周期
|
|
2079
|
+
|
|
2080
|
+
Propose(提案)→ Apply(实施)→ Archive(归档)
|
|
2081
|
+
|
|
2082
|
+
## 文件模板
|
|
2083
|
+
|
|
2084
|
+
```markdown
|
|
2085
|
+
# [功能名称] 规格
|
|
2086
|
+
|
|
2087
|
+
## 状态
|
|
2088
|
+
Proposed | Applied | Completed
|
|
2089
|
+
|
|
2090
|
+
## 需求概述
|
|
2091
|
+
[一句话描述]
|
|
2092
|
+
|
|
2093
|
+
## 涉及文件
|
|
2094
|
+
- 新增:[文件路径]
|
|
2095
|
+
- 修改:[文件路径]
|
|
2096
|
+
|
|
2097
|
+
## 接口定义(如涉及 API)
|
|
2098
|
+
- 路径、方法、请求参数、响应格式
|
|
2099
|
+
|
|
2100
|
+
## 约束条件
|
|
2101
|
+
- [硬性约束]
|
|
2102
|
+
|
|
2103
|
+
## 验收标准
|
|
2104
|
+
- [ ] 标准 1
|
|
2105
|
+
- [ ] 标准 2
|
|
2106
|
+
|
|
2107
|
+
## 变更记录
|
|
2108
|
+
| 日期 | 变更内容 |
|
|
2109
|
+
|------|---------|
|
|
2110
|
+
| YYYY-MM-DD | 初始提案 |
|
|
2111
|
+
```
|
|
2112
|
+
|
|
2113
|
+
## 目录说明
|
|
2114
|
+
|
|
2115
|
+
- `active/` — 进行中的 spec
|
|
2116
|
+
- `archived/` — 已完成的 spec(活文档,不删除)
|
|
2117
|
+
EOF
|
|
2118
|
+
fi
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
# =====================================================================
|
|
2122
|
+
# 主流程:单项目模式(向后兼容)
|
|
2123
|
+
# =====================================================================
|
|
2124
|
+
|
|
2125
|
+
init_single_project() {
|
|
2126
|
+
step "单项目模式初始化"
|
|
2127
|
+
echo ""
|
|
2128
|
+
|
|
2129
|
+
# 步骤1: 检测项目类型
|
|
2130
|
+
info "检测项目类型..."
|
|
2131
|
+
if ! detect_project "."; then
|
|
2132
|
+
warn "未检测到已知项目类型,将创建通用模板"
|
|
2133
|
+
DET_PTYPE="generic"
|
|
2134
|
+
DET_LANG="通用"
|
|
2135
|
+
DET_BACKEND=""
|
|
2136
|
+
DET_FRONTEND=""
|
|
2137
|
+
DET_DATABASE=""
|
|
2138
|
+
DET_BUILD=""
|
|
2139
|
+
else
|
|
2140
|
+
detect_project_details "." "$DET_PTYPE"
|
|
2141
|
+
fi
|
|
2142
|
+
|
|
2143
|
+
PROJECT_NAME="$WORKSPACE_NAME"
|
|
2144
|
+
echo " 名称: $PROJECT_NAME"
|
|
2145
|
+
echo " 类型: $DET_PTYPE"
|
|
2146
|
+
echo " 语言: $DET_LANG"
|
|
2147
|
+
[ -n "$DET_BACKEND" ] && echo " 后端: $DET_BACKEND"
|
|
2148
|
+
[ -n "$DET_FRONTEND" ] && echo " 前端: $DET_FRONTEND"
|
|
2149
|
+
[ -n "$DET_DATABASE" ] && echo " 数据库: $DET_DATABASE"
|
|
2150
|
+
[ -n "$DET_ORM" ] && echo " ORM: $DET_ORM"
|
|
2151
|
+
[ -n "$DET_UI_LIB" ] && echo " UI 组件库: $DET_UI_LIB"
|
|
2152
|
+
[ -n "$DET_STATE_MGMT" ] && echo " 状态管理: $DET_STATE_MGMT"
|
|
2153
|
+
[ -n "$DET_TEST_FRAMEWORK" ] && echo " 测试: $DET_TEST_FRAMEWORK"
|
|
2154
|
+
[ -n "$DET_CACHE" ] && echo " 缓存: $DET_CACHE"
|
|
2155
|
+
[ -n "$DET_MQ" ] && echo " 消息队列: $DET_MQ"
|
|
2156
|
+
echo ""
|
|
2157
|
+
|
|
2158
|
+
# 步骤2: 检查已有配置
|
|
2159
|
+
if [ -d ".claude" ]; then
|
|
2160
|
+
info "检测到已有 .claude/ 目录,增量更新(补全缺失项)"
|
|
2161
|
+
fi
|
|
2162
|
+
|
|
2163
|
+
# 步骤3: 创建目录
|
|
2164
|
+
step "创建目录结构..."
|
|
2165
|
+
mkdir -p .claude/{skills,memory,scripts,commands,rules,specs/active,specs/archived,reports}
|
|
2166
|
+
ok "目录创建完成"
|
|
2167
|
+
|
|
2168
|
+
# 步骤4: 生成配置
|
|
2169
|
+
step "生成配置文件..."
|
|
2170
|
+
generate_settings "." "false"
|
|
2171
|
+
|
|
2172
|
+
# 步骤5: 生成 CLAUDE.md
|
|
2173
|
+
step "生成 CLAUDE.md..."
|
|
2174
|
+
generate_claude_md_single "." "$DET_PTYPE" "$DET_LANG" "$DET_BACKEND" "$DET_FRONTEND" "$DET_DATABASE"
|
|
2175
|
+
|
|
2176
|
+
# 步骤6: 生成命令
|
|
2177
|
+
step "生成 commands..."
|
|
2178
|
+
generate_commands "." "single" "" ""
|
|
2179
|
+
|
|
2180
|
+
# 步骤7: 生成 rules
|
|
2181
|
+
step "生成 rules..."
|
|
2182
|
+
generate_shared_rules "."
|
|
2183
|
+
generate_tech_rules "." "$DET_PTYPE"
|
|
2184
|
+
|
|
2185
|
+
# 步骤8: 生成 skills
|
|
2186
|
+
step "生成 skills..."
|
|
2187
|
+
generate_skills "."
|
|
2188
|
+
|
|
2189
|
+
# 步骤9: 生成知识库
|
|
2190
|
+
step "生成知识库..."
|
|
2191
|
+
generate_memory "." "$DET_PTYPE" "$DET_LANG" "$DET_BACKEND" "$DET_FRONTEND" "$DET_DATABASE" "$PROJECT_NAME" "single"
|
|
2192
|
+
generate_memory_index "." "single"
|
|
2193
|
+
|
|
2194
|
+
# 步骤10: 生成辅助
|
|
2195
|
+
step "生成辅助脚本..."
|
|
2196
|
+
generate_scripts "."
|
|
2197
|
+
generate_spec_structure "."
|
|
2198
|
+
generate_workflow "."
|
|
2199
|
+
generate_readme "." "single" "$DET_PTYPE" "$DET_LANG"
|
|
2200
|
+
|
|
2201
|
+
# 完成
|
|
2202
|
+
echo ""
|
|
2203
|
+
echo "========================================"
|
|
2204
|
+
ok "初始化完成!"
|
|
2205
|
+
echo "========================================"
|
|
2206
|
+
echo ""
|
|
2207
|
+
echo "已创建:"
|
|
2208
|
+
echo " [OK] CLAUDE.md — 项目指令"
|
|
2209
|
+
echo " [OK] .claude/commands/ — 3 个斜杠命令"
|
|
2210
|
+
echo " [OK] .claude/rules/ — 共享 + 技术栈专属规则"
|
|
2211
|
+
echo " [OK] .claude/skills/ — 3 个工作流技能"
|
|
2212
|
+
echo " [OK] .claude/memory/ — 知识库模板"
|
|
2213
|
+
echo ""
|
|
2214
|
+
echo "下一步:"
|
|
2215
|
+
echo " 1. 根据项目实际情况填写 memory/ 下的模板内容"
|
|
2216
|
+
echo " 2. 运行 apprentice doctor 验证健康状态"
|
|
2217
|
+
echo " 3. 在 Claude Code 中试试 /frontend 或 /backend"
|
|
2218
|
+
echo ""
|
|
2219
|
+
echo "项目类型: $DET_PTYPE | 语言: $DET_LANG"
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
# =====================================================================
|
|
2223
|
+
# 主流程:工作区模式
|
|
2224
|
+
# =====================================================================
|
|
2225
|
+
|
|
2226
|
+
init_workspace() {
|
|
2227
|
+
step "工作区模式初始化"
|
|
2228
|
+
echo ""
|
|
2229
|
+
|
|
2230
|
+
# 扫描子项目
|
|
2231
|
+
scan_subprojects
|
|
2232
|
+
print_scan_results
|
|
2233
|
+
|
|
2234
|
+
if [ ${#SUBPROJECTS[@]} -eq 0 ]; then
|
|
2235
|
+
fail "未检测到任何项目,无法初始化工作区"
|
|
2236
|
+
fi
|
|
2237
|
+
|
|
2238
|
+
if [ ${#SUBPROJECTS[@]} -eq 1 ]; then
|
|
2239
|
+
# 只有一个项目且在根目录,走单项目模式
|
|
2240
|
+
local root_only=true
|
|
2241
|
+
for proj in "${SUBPROJECTS[@]}"; do
|
|
2242
|
+
IFS='|' read -r path _ _ _ _ _ _ _ _ <<< "$proj"
|
|
2243
|
+
if [ "$path" != "." ]; then
|
|
2244
|
+
root_only=false
|
|
2245
|
+
break
|
|
2246
|
+
fi
|
|
2247
|
+
done
|
|
2248
|
+
if $root_only; then
|
|
2249
|
+
info "只检测到根目录一个项目,切换到单项目模式"
|
|
2250
|
+
echo ""
|
|
2251
|
+
init_single_project
|
|
2252
|
+
return
|
|
2253
|
+
fi
|
|
2254
|
+
fi
|
|
2255
|
+
|
|
2256
|
+
# 确认
|
|
2257
|
+
echo "将为工作区创建全局配置,并为每个子项目创建专属配置。"
|
|
2258
|
+
read -p "确认继续?[Y/n] " confirm
|
|
2259
|
+
[[ "${confirm:-Y}" =~ ^[Nn] ]] && { info "已取消"; exit 0; }
|
|
2260
|
+
|
|
2261
|
+
# 检查已有配置
|
|
2262
|
+
if [ -d ".claude" ]; then
|
|
2263
|
+
info "检测到已有 .claude/ 目录,增量更新(补全缺失项)"
|
|
2264
|
+
fi
|
|
2265
|
+
|
|
2266
|
+
# ===== 工作区级配置 =====
|
|
2267
|
+
echo ""
|
|
2268
|
+
step "创建工作区级配置..."
|
|
2269
|
+
echo ""
|
|
2270
|
+
|
|
2271
|
+
mkdir -p .claude/{skills,memory,scripts,commands,rules,specs/active,specs/archived,reports}
|
|
2272
|
+
|
|
2273
|
+
# 工作区 settings
|
|
2274
|
+
generate_settings "." "true"
|
|
2275
|
+
|
|
2276
|
+
# 工作区 CLAUDE.md
|
|
2277
|
+
generate_claude_md_workspace "."
|
|
2278
|
+
|
|
2279
|
+
# 工作区 commands
|
|
2280
|
+
generate_commands "." "workspace" "" ""
|
|
2281
|
+
|
|
2282
|
+
# 工作区 rules(共享规则)
|
|
2283
|
+
generate_shared_rules "."
|
|
2284
|
+
|
|
2285
|
+
# 工作区 skills
|
|
2286
|
+
generate_skills "."
|
|
2287
|
+
|
|
2288
|
+
# 工作区 memory
|
|
2289
|
+
generate_memory "." "" "" "" "" "" "$WORKSPACE_NAME" "workspace"
|
|
2290
|
+
generate_memory_index "." "workspace"
|
|
2291
|
+
|
|
2292
|
+
# 工作区 scripts
|
|
2293
|
+
generate_scripts "."
|
|
2294
|
+
generate_spec_structure "."
|
|
2295
|
+
generate_workflow "."
|
|
2296
|
+
generate_readme "." "workspace" "workspace" "multi"
|
|
2297
|
+
|
|
2298
|
+
ok "工作区级配置完成"
|
|
2299
|
+
|
|
2300
|
+
# ===== 子项目配置 =====
|
|
2301
|
+
echo ""
|
|
2302
|
+
step "创建子项目专属配置..."
|
|
2303
|
+
echo ""
|
|
2304
|
+
|
|
2305
|
+
local sub_count=0
|
|
2306
|
+
for proj in "${SUBPROJECTS[@]}"; do
|
|
2307
|
+
IFS='|' read -r path name ptype lang backend frontend database build category <<< "$proj"
|
|
2308
|
+
|
|
2309
|
+
# 跳过根目录本身(如果根目录也是一个项目,它的配置已在工作区级处理)
|
|
2310
|
+
if [ "$path" = "." ]; then
|
|
2311
|
+
info "根目录 $name 作为工作区根,跳过独立初始化"
|
|
2312
|
+
continue
|
|
2313
|
+
fi
|
|
2314
|
+
|
|
2315
|
+
step "初始化子项目: $name ($category)"
|
|
2316
|
+
mkdir -p "$path/.claude/rules" "$path/.claude/memory" "$path/.claude/specs/active" "$path/.claude/specs/archived"
|
|
2317
|
+
|
|
2318
|
+
# 深度检测子项目
|
|
2319
|
+
detect_project_details "$path" "$ptype"
|
|
2320
|
+
|
|
2321
|
+
# 子项目 CLAUDE.md
|
|
2322
|
+
generate_claude_md_subproject "$path" "$name" "$lang" "$backend" "$frontend" "$database"
|
|
2323
|
+
|
|
2324
|
+
# 子项目 settings(轻量版)
|
|
2325
|
+
if [ ! -f "$path/.claude/settings.json" ]; then
|
|
2326
|
+
local proj_perms=""
|
|
2327
|
+
if echo "$ptype" | grep -q "java"; then
|
|
2328
|
+
proj_perms="\"Bash(mvn *)\", \"Bash(gradle *)\","
|
|
2329
|
+
elif echo "$ptype" | grep -q "^go"; then
|
|
2330
|
+
proj_perms="\"Bash(go *)\","
|
|
2331
|
+
elif echo "$ptype" | grep -q "python"; then
|
|
2332
|
+
proj_perms="\"Bash(python *)\", \"Bash(pip *)\","
|
|
2333
|
+
fi
|
|
2334
|
+
if [ -f "$path/package.json" ]; then
|
|
2335
|
+
proj_perms="${proj_perms}\"Bash(npm *)\", \"Bash(node *)\","
|
|
2336
|
+
fi
|
|
2337
|
+
cat > "$path/.claude/settings.json" << SUBSETTINGEOF
|
|
2338
|
+
{
|
|
2339
|
+
"language": "chinese",
|
|
2340
|
+
"permissions": {
|
|
2341
|
+
"allow": [
|
|
2342
|
+
${proj_perms}
|
|
2343
|
+
"Bash(git show *)",
|
|
2344
|
+
"Bash(git diff *)",
|
|
2345
|
+
"Bash(git log *)",
|
|
2346
|
+
"Bash(git diff-tree *)",
|
|
2347
|
+
"Read(*)",
|
|
2348
|
+
"Edit(*)",
|
|
2349
|
+
"Write(*)"
|
|
2350
|
+
],
|
|
2351
|
+
"deny": [
|
|
2352
|
+
"Bash(git push --force)",
|
|
2353
|
+
"Bash(rm -rf *)"
|
|
2354
|
+
]
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
SUBSETTINGEOF
|
|
2358
|
+
fi
|
|
2359
|
+
|
|
2360
|
+
# 子项目 rules(技术栈专属)
|
|
2361
|
+
generate_tech_rules "$path" "$ptype"
|
|
2362
|
+
|
|
2363
|
+
# 子项目 memory
|
|
2364
|
+
generate_memory "$path" "$ptype" "$lang" "$backend" "$frontend" "$database" "$name" "subproject"
|
|
2365
|
+
|
|
2366
|
+
# 子项目 specs
|
|
2367
|
+
generate_spec_structure "$path"
|
|
2368
|
+
|
|
2369
|
+
sub_count=$((sub_count + 1))
|
|
2370
|
+
ok "子项目 $name 配置完成"
|
|
2371
|
+
echo ""
|
|
2372
|
+
done
|
|
2373
|
+
|
|
2374
|
+
# ===== 完成 =====
|
|
2375
|
+
echo "========================================"
|
|
2376
|
+
ok "工作区初始化完成!"
|
|
2377
|
+
echo "========================================"
|
|
2378
|
+
echo ""
|
|
2379
|
+
echo "已创建:"
|
|
2380
|
+
echo " [OK] 工作区全局 .claude/ — 共享规则、命令、知识库"
|
|
2381
|
+
echo " [OK] ${sub_count} 个子项目专属 .claude/ — 技术栈专属规则和知识库"
|
|
2382
|
+
echo ""
|
|
2383
|
+
echo "工作方式:"
|
|
2384
|
+
echo " 1. cd <子项目目录> → 直接说需求(加载项目专属配置)"
|
|
2385
|
+
echo " 2. 在工作区根目录 → 使用 /frontend 或 /backend 查看子项目列表"
|
|
2386
|
+
echo " 3. 跨项目开发 → 在工作区根目录使用 /fullstack"
|
|
2387
|
+
echo ""
|
|
2388
|
+
echo "下一步:"
|
|
2389
|
+
echo " 1. 填写各子项目 memory/ 下的模板内容"
|
|
2390
|
+
echo " 2. 运行 apprentice doctor 验证健康状态"
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
# =====================================================================
|
|
2394
|
+
# 主流程:子项目单独初始化
|
|
2395
|
+
# =====================================================================
|
|
2396
|
+
|
|
2397
|
+
init_single_subproject() {
|
|
2398
|
+
local dir="$1"
|
|
2399
|
+
|
|
2400
|
+
if [ ! -d "$dir" ]; then
|
|
2401
|
+
fail "目录不存在: $dir"
|
|
2402
|
+
fi
|
|
2403
|
+
|
|
2404
|
+
cd "$dir"
|
|
2405
|
+
local proj_name=$(basename "$(pwd)")
|
|
2406
|
+
|
|
2407
|
+
step "子项目初始化: $proj_name"
|
|
2408
|
+
echo ""
|
|
2409
|
+
|
|
2410
|
+
if ! detect_project "."; then
|
|
2411
|
+
fail "未在 $proj_name 中检测到项目标记文件"
|
|
2412
|
+
fi
|
|
2413
|
+
|
|
2414
|
+
detect_project_details "." "$DET_PTYPE"
|
|
2415
|
+
|
|
2416
|
+
echo " 名称: $proj_name"
|
|
2417
|
+
echo " 类型: $DET_PTYPE"
|
|
2418
|
+
echo " 语言: $DET_LANG"
|
|
2419
|
+
[ -n "$DET_BACKEND" ] && echo " 后端: $DET_BACKEND"
|
|
2420
|
+
[ -n "$DET_FRONTEND" ] && echo " 前端: $DET_FRONTEND"
|
|
2421
|
+
[ -n "$DET_DATABASE" ] && echo " 数据库: $DET_DATABASE"
|
|
2422
|
+
echo ""
|
|
2423
|
+
|
|
2424
|
+
mkdir -p .claude/{rules,memory,specs/active,specs/archived}
|
|
2425
|
+
|
|
2426
|
+
generate_claude_md_subproject "." "$proj_name" "$DET_LANG" "$DET_BACKEND" "$DET_FRONTEND" "$DET_DATABASE"
|
|
2427
|
+
generate_tech_rules "." "$DET_PTYPE"
|
|
2428
|
+
generate_memory "." "$DET_PTYPE" "$DET_LANG" "$DET_BACKEND" "$DET_FRONTEND" "$DET_DATABASE" "$proj_name" "subproject"
|
|
2429
|
+
generate_spec_structure "."
|
|
2430
|
+
|
|
2431
|
+
echo ""
|
|
2432
|
+
ok "子项目 $proj_name 初始化完成"
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
# =====================================================================
|
|
2436
|
+
# 主入口
|
|
2437
|
+
# =====================================================================
|
|
2438
|
+
|
|
2439
|
+
info "目标目录: $TARGET_DIR"
|
|
2440
|
+
echo ""
|
|
2441
|
+
|
|
2442
|
+
case "$MODE" in
|
|
2443
|
+
scan)
|
|
2444
|
+
scan_subprojects
|
|
2445
|
+
print_scan_results
|
|
2446
|
+
;;
|
|
2447
|
+
workspace)
|
|
2448
|
+
init_workspace
|
|
2449
|
+
;;
|
|
2450
|
+
project)
|
|
2451
|
+
init_single_subproject "$PROJECT_DIR"
|
|
2452
|
+
;;
|
|
2453
|
+
auto)
|
|
2454
|
+
# 自动检测模式
|
|
2455
|
+
scan_subprojects
|
|
2456
|
+
|
|
2457
|
+
# 判断:单项目 or 多项目
|
|
2458
|
+
AUTO_ROOT_ONLY=false
|
|
2459
|
+
if [ ${#SUBPROJECTS[@]} -eq 1 ]; then
|
|
2460
|
+
IFS='|' read -r path _ _ _ _ _ _ _ _ <<< "${SUBPROJECTS[0]}"
|
|
2461
|
+
[ "$path" = "." ] && AUTO_ROOT_ONLY=true
|
|
2462
|
+
fi
|
|
2463
|
+
|
|
2464
|
+
if $AUTO_ROOT_ONLY || [ ${#SUBPROJECTS[@]} -eq 0 ]; then
|
|
2465
|
+
# 单项目或无项目 — 走原有单项目流程
|
|
2466
|
+
init_single_project
|
|
2467
|
+
else
|
|
2468
|
+
# 多项目 — 走工作区流程
|
|
2469
|
+
print_scan_results
|
|
2470
|
+
echo "检测到多个子项目,进入工作区模式。"
|
|
2471
|
+
echo "如需单项目模式,请使用: init.sh --project <目录>"
|
|
2472
|
+
echo ""
|
|
2473
|
+
init_workspace
|
|
2474
|
+
fi
|
|
2475
|
+
;;
|
|
2476
|
+
esac
|