sillyspec 3.20.2 → 3.20.4
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/.claude/skills/sillyspec-archive/SKILL.md +21 -21
- package/.claude/skills/sillyspec-auto/SKILL.md +83 -83
- package/.claude/skills/sillyspec-brainstorm/SKILL.md +44 -44
- package/.claude/skills/sillyspec-commit/SKILL.md +106 -106
- package/.claude/skills/sillyspec-continue/SKILL.md +45 -45
- package/.claude/skills/sillyspec-doctor/SKILL.md +31 -31
- package/.claude/skills/sillyspec-execute/SKILL.md +30 -30
- package/.claude/skills/sillyspec-explore/SKILL.md +109 -109
- package/.claude/skills/sillyspec-knowledge/SKILL.md +269 -269
- package/.claude/skills/sillyspec-plan/SKILL.md +21 -21
- package/.claude/skills/sillyspec-propose/SKILL.md +21 -21
- package/.claude/skills/sillyspec-quick/SKILL.md +21 -21
- package/.claude/skills/sillyspec-resume/SKILL.md +68 -68
- package/.claude/skills/sillyspec-scan/SKILL.md +21 -21
- package/.claude/skills/sillyspec-state/SKILL.md +54 -54
- package/.claude/skills/sillyspec-status/SKILL.md +21 -21
- package/.claude/skills/sillyspec-verify/SKILL.md +21 -21
- package/.claude/skills/sillyspec-workspace/SKILL.md +157 -157
- package/.husky/pre-push +13 -13
- package/CLAUDE.md +18 -18
- package/README.md +198 -188
- package/SKILL.md +90 -91
- package/bin/sillyspec.js +2 -2
- package/docs/brainstorm-plan-contract.md +64 -64
- package/docs/plan-execute-contract.md +123 -123
- package/docs/platform-scan-protocol.md +298 -298
- package/docs/revision-mode.md +115 -115
- package/docs/sillyspec/file-lifecycle/known-implementation-gaps.md +99 -99
- package/docs/sillyspec/file-lifecycle/platform-workflows-sync.md +218 -218
- package/docs/sillyspec/file-lifecycle/stage-artifacts.md +167 -167
- package/docs/sillyspec/file-lifecycle/storage-and-state.md +148 -148
- package/docs/sillyspec/file-lifecycle/worktree-and-guard.md +211 -193
- package/docs/sillyspec/file-lifecycle.md +125 -125
- package/docs/workflow-contract-regression.md +106 -106
- package/docs/worktree-isolation.md +252 -252
- package/package.json +40 -40
- package/packages/dashboard/dist/assets/index-Bq_Z2hne.js +7446 -7446
- package/packages/dashboard/dist/assets/index-O2W5RV4z.css +1 -1
- package/packages/dashboard/dist/index.html +16 -16
- package/packages/dashboard/index.html +15 -15
- package/packages/dashboard/package-lock.json +2384 -2384
- package/packages/dashboard/package.json +25 -25
- package/packages/dashboard/server/executor.js +86 -86
- package/packages/dashboard/server/index.js +588 -588
- package/packages/dashboard/server/parser.js +526 -526
- package/packages/dashboard/server/watcher.js +344 -344
- package/packages/dashboard/src/App.vue +558 -558
- package/packages/dashboard/src/components/ActionBar.vue +93 -93
- package/packages/dashboard/src/components/CommandPalette.vue +96 -96
- package/packages/dashboard/src/components/DetailPanel.vue +137 -137
- package/packages/dashboard/src/components/LogStream.vue +65 -65
- package/packages/dashboard/src/components/PipelineStage.vue +95 -95
- package/packages/dashboard/src/components/PipelineView.vue +156 -156
- package/packages/dashboard/src/components/ProjectList.vue +210 -210
- package/packages/dashboard/src/components/StageBadge.vue +67 -67
- package/packages/dashboard/src/components/StepCard.vue +94 -94
- package/packages/dashboard/src/components/detail/DocsDetail.vue +48 -48
- package/packages/dashboard/src/components/detail/GitDetail.vue +61 -61
- package/packages/dashboard/src/components/detail/TechDetail.vue +43 -43
- package/packages/dashboard/src/composables/useDashboard.js +170 -170
- package/packages/dashboard/src/composables/useKeyboard.js +119 -119
- package/packages/dashboard/src/composables/useWebSocket.js +129 -129
- package/packages/dashboard/src/main.js +8 -8
- package/packages/dashboard/src/style.css +132 -132
- package/packages/dashboard/vite.config.js +18 -18
- package/src/brainstorm-postcheck.js +158 -158
- package/src/change-list.js +52 -52
- package/src/change-risk-profile.js +352 -352
- package/src/classify-change.js +73 -73
- package/src/constants.js +70 -70
- package/src/contract-matrix.js +278 -278
- package/src/db.js +201 -201
- package/src/endpoint-extractor.js +315 -315
- package/src/hooks/claude-pre-tool-use.cjs +125 -125
- package/src/hooks/worktree-guard.js +653 -653
- package/src/index.js +922 -900
- package/src/init.js +431 -431
- package/src/knowledge-match.js +130 -130
- package/src/migrate.js +117 -117
- package/src/modules.js +482 -482
- package/src/progress.js +1734 -1734
- package/src/run.js +3465 -3358
- package/src/scan-postcheck.js +387 -383
- package/src/setup.js +398 -398
- package/src/stage-contract.js +700 -700
- package/src/stages/archive.js +160 -160
- package/src/stages/brainstorm-auto.js +229 -229
- package/src/stages/brainstorm.js +645 -645
- package/src/stages/doctor.js +365 -365
- package/src/stages/execute.js +625 -625
- package/src/stages/explore.js +34 -34
- package/src/stages/index.js +29 -29
- package/src/stages/knowledge.js +498 -498
- package/src/stages/plan-postcheck.js +511 -513
- package/src/stages/plan.js +582 -582
- package/src/stages/propose.js +174 -174
- package/src/stages/quick.js +82 -82
- package/src/stages/scan.js +558 -558
- package/src/stages/status.js +65 -65
- package/src/stages/verify.js +322 -322
- package/src/sync.js +497 -497
- package/src/task-review.js +346 -346
- package/src/workflow.js +785 -785
- package/src/worktree-apply.js +549 -549
- package/src/worktree-deps.js +185 -0
- package/src/worktree.js +982 -932
- package/templates/workflows/archive-impact.yaml +79 -79
- package/templates/workflows/scan-docs.yaml +132 -132
- package/test/brainstorm-plan-contract.test.mjs +273 -273
- package/test/check-syntax.mjs +26 -26
- package/test/contract-artifacts.test.mjs +323 -323
- package/test/decision-supersede.test.mjs +277 -277
- package/test/knowledge-match.test.mjs +231 -231
- package/test/plan-execute-contract.test.mjs +330 -330
- package/test/plan-optimization.test.mjs +572 -572
- package/test/platform-artifacts.test.mjs +166 -166
- package/test/platform-failure-samples.test.mjs +199 -199
- package/test/platform-recovery-chain.test.mjs +167 -167
- package/test/platform-recovery.test.mjs +136 -136
- package/test/platform-scan-p0.test.mjs +168 -168
- package/test/revision-v1.test.mjs +1145 -1145
- package/test/run-scan-project-parse.test.mjs +200 -200
- package/test/run-tests.mjs +48 -48
- package/test/scan-knowledge.test.mjs +175 -175
- package/test/scan-paths.test.mjs +68 -68
- package/test/scan-postcheck.test.mjs +197 -197
- package/test/spec-dir.test.mjs +206 -206
- package/test/stage-contract.test.mjs +299 -299
- package/test/stage-definitions.test.mjs +39 -39
- package/test/wait-gates.test.mjs +496 -496
- package/test/worktree-deps-provision.test.mjs +148 -0
- package/test/worktree-guard.test.mjs +71 -71
- package/test/worktree-native-overlay.test.mjs +188 -188
package/src/stages/doctor.js
CHANGED
|
@@ -1,365 +1,365 @@
|
|
|
1
|
-
// SillySpec Doctor — 项目自检阶段
|
|
2
|
-
// 检查项通过 prompt 中的 bash 命令执行,此文件仅定义步骤结构
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export const definition = {
|
|
6
|
-
name: 'doctor',
|
|
7
|
-
title: '项目自检',
|
|
8
|
-
description: '检查 SillySpec 配置、构建环境和外部依赖',
|
|
9
|
-
auxiliary: true,
|
|
10
|
-
steps: [
|
|
11
|
-
{
|
|
12
|
-
name: 'SillySpec 内部检查',
|
|
13
|
-
prompt: `运行 SillySpec 内部检查。逐项执行以下命令并汇总结果:
|
|
14
|
-
|
|
15
|
-
### 1. 目录结构完整性
|
|
16
|
-
\`\`\`bash
|
|
17
|
-
# 检查 .sillyspec/ 及子目录
|
|
18
|
-
for d in .sillyspec .sillyspec/projects .sillyspec/docs .sillyspec/changes .sillyspec/.runtime; do
|
|
19
|
-
[ -d "$d" ] && echo "✅ $d" || echo "❌ $d"
|
|
20
|
-
done
|
|
21
|
-
# 检查 sillyspec.db(SQLite 权威状态源)
|
|
22
|
-
DB_FILE='.sillyspec/.runtime/sillyspec.db'
|
|
23
|
-
[ -f "$DB_FILE" ] && echo "✅ sillyspec.db 存在" || echo "❌ sillyspec.db 不存在"
|
|
24
|
-
sqlite3 "$DB_FILE" "SELECT count(*) FROM project" 2>/dev/null && echo "✅ sillyspec.db 可查询" || echo "⚠️ sillyspec.db 不可查询"
|
|
25
|
-
\`\`\`
|
|
26
|
-
|
|
27
|
-
### 2. 项目配置检查
|
|
28
|
-
\`\`\`bash
|
|
29
|
-
ls .sillyspec/projects/*.yaml 2>/dev/null
|
|
30
|
-
# 对每个 yaml 文件,检查 name 和 path 字段,验证 path 存在
|
|
31
|
-
for f in .sillyspec/projects/*.yaml; do
|
|
32
|
-
[ -f "$f" ] || continue
|
|
33
|
-
name=$(grep '^name:' "$f" | head -1 | sed 's/^name:[[:space:]]*//')
|
|
34
|
-
p=$(grep '^path:' "$f" | head -1 | sed 's/^path:[[:space:]]*//')
|
|
35
|
-
[ -z "$name" ] && echo "⚠️ $(basename $f) — 缺少 name"
|
|
36
|
-
[ -z "$p" ] && echo "⚠️ $(basename $f) — 缺少 path"
|
|
37
|
-
[ -n "$p" ] && [ ! -d "$p" ] && echo "❌ $(basename $f) — path 不存在: $p"
|
|
38
|
-
[ -n "$name" ] && [ -n "$p" ] && [ -d "$p" ] && echo "✅ $(basename $f) — $name ($p)"
|
|
39
|
-
done
|
|
40
|
-
\`\`\`
|
|
41
|
-
|
|
42
|
-
### 3. 进度数据一致性
|
|
43
|
-
\`\`\`bash
|
|
44
|
-
# 从 sillyspec.db 读取活跃变更并检查目录存在性
|
|
45
|
-
DB_FILE='.sillyspec/.runtime/sillyspec.db'
|
|
46
|
-
if [ ! -f "$DB_FILE" ]; then echo "⚠️ sillyspec.db 不存在"; exit 0; fi
|
|
47
|
-
ACTIVE_CHANGE=$(sqlite3 "$DB_FILE" "SELECT name FROM changes WHERE status='active' ORDER BY last_active DESC LIMIT 1" 2>/dev/null)
|
|
48
|
-
if [ -z "$ACTIVE_CHANGE" ]; then echo "ℹ️ 无当前变更"; exit 0; fi
|
|
49
|
-
echo "当前变更: $ACTIVE_CHANGE"
|
|
50
|
-
DIR=".sillyspec/changes/$ACTIVE_CHANGE"
|
|
51
|
-
[ -d "$DIR" ] && echo "✅ 变更目录存在: $ACTIVE_CHANGE" || echo "❌ 变更目录不存在: $ACTIVE_CHANGE"
|
|
52
|
-
# 检查各阶段状态
|
|
53
|
-
sqlite3 -header -column "$DB_FILE" "SELECT stage, status FROM stages s JOIN changes c ON s.change_id=c.id WHERE c.name='$ACTIVE_CHANGE' ORDER BY s.stage" 2>/dev/null || echo "⚠️ 无法查询阶段数据"
|
|
54
|
-
\`\`\`
|
|
55
|
-
|
|
56
|
-
### 4. 孤儿文件检查
|
|
57
|
-
\`\`\`bash
|
|
58
|
-
DB_FILE='.sillyspec/.runtime/sillyspec.db'
|
|
59
|
-
if [ ! -f "$DB_FILE" ]; then echo "⚠️ sillyspec.db 不存在"; exit 0; fi
|
|
60
|
-
node -e "
|
|
61
|
-
const fs = require('fs');
|
|
62
|
-
const dir = '.sillyspec/changes';
|
|
63
|
-
if (!fs.existsSync(dir)) { console.log('ℹ️ changes/ 目录不存在'); process.exit(0); }
|
|
64
|
-
const subs = fs.readdirSync(dir).filter(f => fs.statSync(dir+'/'+f).isDirectory());
|
|
65
|
-
if (subs.length === 0) { console.log('ℹ️ 无变更目录'); process.exit(0); }
|
|
66
|
-
const { execSync } = require('child_process');
|
|
67
|
-
let known;
|
|
68
|
-
try { const rows = execSync('sqlite3 -json \".sillyspec/.runtime/sillyspec.db\" \"SELECT name FROM changes WHERE status=\\\"active\\\"\"', {encoding:'utf8'}).trim(); known = new Set(JSON.parse(rows).map(r => r.name)); } catch { known = new Set(); }
|
|
69
|
-
subs.forEach(s => {
|
|
70
|
-
console.log(known.has(s) ? '✅ ' + s + ' — 已关联' : '⚠️ ' + s + ' — 孤儿目录(可清理)');
|
|
71
|
-
});
|
|
72
|
-
"
|
|
73
|
-
\`\`\`
|
|
74
|
-
|
|
75
|
-
### 5. 配置文件检查
|
|
76
|
-
\`\`\`bash
|
|
77
|
-
# 检查 local.yaml 和 STACK.md
|
|
78
|
-
for f in .sillyspec/projects/*.yaml; do
|
|
79
|
-
[ -f "$f" ] || continue
|
|
80
|
-
name=$(grep '^name:' "$f" | head -1 | sed 's/^name:[[:space:]]*//')
|
|
81
|
-
p=$(grep '^path:' "$f" | head -1 | sed 's/^path:[[:space:]]*//')
|
|
82
|
-
[ -z "$p" ] && continue
|
|
83
|
-
local_yaml="$p/.sillyspec/local.yaml"
|
|
84
|
-
stack_md="$p/.sillyspec/STACK.md"
|
|
85
|
-
[ -f "$local_yaml" ] && echo "✅ local.yaml ($name)" || echo "⚠️ local.yaml ($name) — 不存在"
|
|
86
|
-
if [ -f "$local_yaml" ]; then
|
|
87
|
-
grep -q 'test:' "$local_yaml" && echo " ✅ test 命令已配置" || echo " ⚠️ 缺少 test 命令"
|
|
88
|
-
fi
|
|
89
|
-
[ -f "$stack_md" ] && echo "✅ STACK.md ($name)" || echo "⚠️ STACK.md ($name) — 不存在"
|
|
90
|
-
done
|
|
91
|
-
\`\`\`
|
|
92
|
-
|
|
93
|
-
### 6. Worktree 隔离环境检查
|
|
94
|
-
\`\`\`bash
|
|
95
|
-
# 检测当前目录是否在 submodule 中
|
|
96
|
-
SUPERPROJECT=$(git rev-parse --show-superproject-working-tree 2>/dev/null)
|
|
97
|
-
if [ -n "$SUPERPROJECT" ]; then
|
|
98
|
-
echo "⚠️ 当前目录在 git submodule 内,worktree 隔离不可用"
|
|
99
|
-
else
|
|
100
|
-
echo "✅ 不在 submodule 中"
|
|
101
|
-
fi
|
|
102
|
-
|
|
103
|
-
# 检测是否已在 linked worktree 中
|
|
104
|
-
GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
|
|
105
|
-
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
|
|
106
|
-
if [ "$GIT_DIR" != "$GIT_COMMON" ] && [ -z "$SUPERPROJECT" ]; then
|
|
107
|
-
echo "✅ 已在 linked worktree 中"
|
|
108
|
-
else
|
|
109
|
-
echo "ℹ️ 在主仓库中(非 worktree)"
|
|
110
|
-
fi
|
|
111
|
-
|
|
112
|
-
# 检查 worktree 存储目录是否被 .gitignore 忽略
|
|
113
|
-
WT_DIR='.sillyspec/.runtime/worktrees'
|
|
114
|
-
if git check-ignore -q "$WT_DIR" 2>/dev/null; then
|
|
115
|
-
echo "✅ worktree 目录已被 .gitignore 忽略 ($WT_DIR)"
|
|
116
|
-
else
|
|
117
|
-
echo "❌ worktree 目录未被 .gitignore 忽略 ($WT_DIR) — worktree 创建将被阻断"
|
|
118
|
-
echo " 修复: 在 .gitignore 中添加 $WT_DIR/"
|
|
119
|
-
fi
|
|
120
|
-
|
|
121
|
-
# 检查 DB 中的 isolation 状态
|
|
122
|
-
DB_FILE='.sillyspec/.runtime/sillyspec.db'
|
|
123
|
-
if [ -f "$DB_FILE" ]; then
|
|
124
|
-
echo ""
|
|
125
|
-
echo "isolation 状态(来自 sillyspec.db):"
|
|
126
|
-
sqlite3 -header -column "$DB_FILE" "SELECT name, isolation_status AS status, isolation_mode AS mode, isolation_reason AS reason FROM changes WHERE status='active'" 2>/dev/null || echo "⚠️ 查询 isolation 失败"
|
|
127
|
-
else
|
|
128
|
-
echo ""
|
|
129
|
-
echo "ℹ️ sillyspec.db 不存在(尚未初始化)"
|
|
130
|
-
fi
|
|
131
|
-
else
|
|
132
|
-
echo "ℹ️ gate-status.json 不存在(尚未进入 execute 阶段)"
|
|
133
|
-
fi
|
|
134
|
-
\`\`\`\n
|
|
135
|
-
### 输出
|
|
136
|
-
汇总所有检查结果,按以下格式:
|
|
137
|
-
\`\`\`
|
|
138
|
-
## SillySpec 内部
|
|
139
|
-
✅/⚠️/❌ 各项状态
|
|
140
|
-
\`\`\`
|
|
141
|
-
|
|
142
|
-
### 注意
|
|
143
|
-
- 不要编造路径或结果,严格基于命令输出
|
|
144
|
-
- 如果 .sillyspec/ 不存在,直接输出 ❌ 并跳过后续检查`,
|
|
145
|
-
outputHint: 'SillySpec 内部检查结果',
|
|
146
|
-
optional: false
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
name: '构建环境检查',
|
|
150
|
-
prompt: `检查项目构建环境。先探测项目使用的构建工具,再逐项检查可用性。
|
|
151
|
-
|
|
152
|
-
### 1. 探测构建工具
|
|
153
|
-
\`\`\`bash
|
|
154
|
-
# 确定项目路径(使用 sillyspec.db 中的项目路径或当前目录)
|
|
155
|
-
PROJECT_DIR=$(sqlite3 -json '.sillyspec/.runtime/sillyspec.db' "SELECT name FROM project WHERE id=1" 2>/dev/null | node -e "const r=JSON.parse(require('fs').readFileSync(0,'utf8'));console.log(r.length>0&&r[0].name?r[0].name:'.')" 2>/dev/null || node -e "
|
|
156
|
-
const fs=require('fs');
|
|
157
|
-
try{const files=fs.readdirSync('.sillyspec/projects').filter(f=>f.endsWith('.yaml'));
|
|
158
|
-
if(files.length>0){const c=fs.readFileSync('.sillyspec/projects/'+files[0],'utf8');const m=c.match(/^path:\\s*(.+)/m);console.log(m?m[1].trim():'.')}else console.log('.')
|
|
159
|
-
}catch{console.log('.')}
|
|
160
|
-
" 2>/dev/null)
|
|
161
|
-
echo "项目目录: $PROJECT_DIR"
|
|
162
|
-
|
|
163
|
-
# 探测构建工具
|
|
164
|
-
for f in pom.xml build.gradle package.json requirements.txt pyproject.toml go.mod Cargo.toml; do
|
|
165
|
-
[ -f "$PROJECT_DIR/$f" ] && echo "检测到: $f"
|
|
166
|
-
done
|
|
167
|
-
[ -f "$PROJECT_DIR/.sillyspec/STACK.md" ] && cat "$PROJECT_DIR/.sillyspec/STACK.md" | head -30
|
|
168
|
-
\`\`\`
|
|
169
|
-
|
|
170
|
-
### 2. 构建工具可用性
|
|
171
|
-
根据上面检测到的工具,运行对应检查(未检测到的跳过):
|
|
172
|
-
|
|
173
|
-
**Maven 项目:**
|
|
174
|
-
\`\`\`bash
|
|
175
|
-
timeout 10 mvn -v 2>/dev/null | head -1 && echo "✅ Maven 可用" || echo "❌ Maven 不可用"
|
|
176
|
-
[ -f ~/.m2/settings.xml ] && echo "✅ Maven settings.xml 存在" || echo "⚠️ Maven settings.xml 不存在"
|
|
177
|
-
timeout 10 java -version 2>&1 | head -1
|
|
178
|
-
\`\`\`
|
|
179
|
-
|
|
180
|
-
**Gradle 项目:**
|
|
181
|
-
\`\`\`bash
|
|
182
|
-
timeout 10 gradle -v 2>/dev/null | head -1 && echo "✅ Gradle 可用" || echo "❌ Gradle 不可用"
|
|
183
|
-
\`\`\`
|
|
184
|
-
|
|
185
|
-
**Node.js 项目:**
|
|
186
|
-
\`\`\`bash
|
|
187
|
-
timeout 5 node -v 2>/dev/null && echo "✅ Node.js 可用" || echo "❌ Node.js 不可用"
|
|
188
|
-
timeout 5 npm -v 2>/dev/null && echo "✅ npm 可用" || echo "❌ npm 不可用"
|
|
189
|
-
timeout 5 pnpm -v 2>/dev/null && echo "✅ pnpm 可用" || echo "ℹ️ pnpm 未安装"
|
|
190
|
-
# 检查 registry
|
|
191
|
-
npm config get registry 2>/dev/null
|
|
192
|
-
\`\`\`
|
|
193
|
-
|
|
194
|
-
**Python 项目:**
|
|
195
|
-
\`\`\`bash
|
|
196
|
-
timeout 5 python3 --version 2>/dev/null && echo "✅ Python3 可用" || echo "❌ Python3 不可用"
|
|
197
|
-
timeout 5 pip3 --version 2>/dev/null && echo "✅ pip3 可用" || echo "❌ pip3 不可用"
|
|
198
|
-
\`\`\`
|
|
199
|
-
|
|
200
|
-
### 3. Maven 私服检查(仅 Maven 项目)
|
|
201
|
-
\`\`\`bash
|
|
202
|
-
# 从 settings.xml 提取仓库地址
|
|
203
|
-
if [ -f ~/.m2/settings.xml ]; then
|
|
204
|
-
grep -oP 'https?://[^<"]+:[0-9]+' ~/.m2/settings.xml 2>/dev/null | sort -u | while read url; do
|
|
205
|
-
timeout 5 curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null
|
|
206
|
-
echo " — $url"
|
|
207
|
-
done
|
|
208
|
-
fi
|
|
209
|
-
# 从 pom.xml 提取
|
|
210
|
-
if [ -f "$PROJECT_DIR/pom.xml" ]; then
|
|
211
|
-
grep -oP 'https?://[^<"]+:[0-9]+' "$PROJECT_DIR/pom.xml" 2>/dev/null | sort -u | while read url; do
|
|
212
|
-
code=$(timeout 5 curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null)
|
|
213
|
-
[ "$code" = "000" ] && echo "❌ 私服不可达: $url(超时)" || echo "✅ 私服可达 ($code): $url"
|
|
214
|
-
done
|
|
215
|
-
fi
|
|
216
|
-
\`\`\`
|
|
217
|
-
|
|
218
|
-
### 4. 运行时环境
|
|
219
|
-
\`\`\`bash
|
|
220
|
-
timeout 5 node -v 2>/dev/null && echo "Node.js: $(node -v)" || echo "❌ Node.js 未安装"
|
|
221
|
-
timeout 5 git --version 2>/dev/null && echo "Git: $(git --version)" || echo "❌ Git 未安装"
|
|
222
|
-
timeout 10 git remote -v 2>/dev/null | head -2
|
|
223
|
-
timeout 5 git ls-remote --heads origin 2>/dev/null >/dev/null && echo "✅ Git remote 可达" || echo "⚠️ Git remote 不可达"
|
|
224
|
-
timeout 5 java -version 2>&1 | head -1
|
|
225
|
-
timeout 5 python3 --version 2>/dev/null
|
|
226
|
-
\`\`\`
|
|
227
|
-
|
|
228
|
-
### 输出
|
|
229
|
-
汇总所有检查结果:
|
|
230
|
-
\`\`\`
|
|
231
|
-
## 构建环境
|
|
232
|
-
✅/⚠️/❌ 各项状态
|
|
233
|
-
\`\`\`
|
|
234
|
-
|
|
235
|
-
### 注意
|
|
236
|
-
- 未检测到的构建工具直接跳过,不要报错
|
|
237
|
-
- timeout 超时的命令视为不可用
|
|
238
|
-
- 不编造结果`,
|
|
239
|
-
outputHint: '构建环境检查结果',
|
|
240
|
-
optional: false
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
name: '外部依赖检查',
|
|
244
|
-
prompt: `检查外部依赖工具是否可用。
|
|
245
|
-
|
|
246
|
-
### 1. Context7 MCP
|
|
247
|
-
\`\`\`bash
|
|
248
|
-
# 检查 MCP 配置
|
|
249
|
-
for f in ~/.config/claude/claude_desktop_config.json ~/.cursor/mcp.json ~/.openclaw/mcp.json; do
|
|
250
|
-
[ -f "$f" ] && echo "MCP 配置文件: $f" && grep -i context7 "$f" 2>/dev/null && echo "✅ Context7 已配置" || true
|
|
251
|
-
done
|
|
252
|
-
# 也检查 sillyspec 自身的 setup
|
|
253
|
-
node -e "
|
|
254
|
-
try{const m=require(require('path').join(require('os').homedir(),'.sillyspec','config.json'));console.log('✅ sillyspec config 存在')}catch{console.log('ℹ️ 无 sillyspec 全局配置')}
|
|
255
|
-
" 2>/dev/null
|
|
256
|
-
\`\`\`
|
|
257
|
-
|
|
258
|
-
### 2. grep.app
|
|
259
|
-
\`\`\`bash
|
|
260
|
-
timeout 5 curl -s -o /dev/null -w "%{http_code}" https://grep.app 2>/dev/null | grep -q "200" && echo "✅ grep.app 可达" || echo "⚠️ grep.app 不可达"
|
|
261
|
-
\`\`\`
|
|
262
|
-
|
|
263
|
-
### 3. 其他 AI 工具(可选)
|
|
264
|
-
\`\`\`bash
|
|
265
|
-
# 检查常用 AI/开发工具
|
|
266
|
-
timeout 5 which gh 2>/dev/null && echo "✅ GitHub CLI 可用" || echo "ℹ️ GitHub CLI 未安装"
|
|
267
|
-
timeout 5 which docker 2>/dev/null && echo "✅ Docker 可用" || echo "ℹ️ Docker 未安装"
|
|
268
|
-
\`\`\`
|
|
269
|
-
|
|
270
|
-
### 输出
|
|
271
|
-
\`\`\`
|
|
272
|
-
## 外部依赖
|
|
273
|
-
✅/⚠️/❌ 各项状态
|
|
274
|
-
\`\`\`
|
|
275
|
-
|
|
276
|
-
### 注意
|
|
277
|
-
- 不编造结果
|
|
278
|
-
- 工具未安装用 ℹ️ 标记(非错误),不可达用 ⚠️`,
|
|
279
|
-
outputHint: '外部依赖检查结果',
|
|
280
|
-
optional: false
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
name: '模块文档健康检查',
|
|
284
|
-
prompt: `检查模块索引和卡片文档的健康状态。
|
|
285
|
-
|
|
286
|
-
### 操作
|
|
287
|
-
1. 运行 \`sillyspec modules status\` 查看模块索引概览
|
|
288
|
-
2. 读取 \`.sillyspec/docs/<project>/modules/_module-map.yaml\`
|
|
289
|
-
3. 对每个模块,检查:
|
|
290
|
-
- module_id 是否有对应的卡片文件(modules/<module-id>.md)
|
|
291
|
-
- 卡片文件是否有有效的 frontmatter(schema_version, doc_type, module_id)
|
|
292
|
-
- 人工备注标记是否配对(MANUAL_NOTES_START 和 MANUAL_NOTES_END 必须成对出现)
|
|
293
|
-
- needs_review 为 true 的模块列表
|
|
294
|
-
4. 汇总结果
|
|
295
|
-
|
|
296
|
-
### 输出格式
|
|
297
|
-
\`\`\`
|
|
298
|
-
📋 模块文档健康检查
|
|
299
|
-
✅ _module-map.yaml — 存在,N 个模块
|
|
300
|
-
⚠️ auth-service — needs_review=true,原因:...
|
|
301
|
-
❌ payment-service — 卡片文件缺失
|
|
302
|
-
✅ 所有模块人工备注标记配对正常
|
|
303
|
-
\`\`\`
|
|
304
|
-
|
|
305
|
-
### 注意
|
|
306
|
-
- 如果 _module-map.yaml 不存在,输出"模块索引未生成,建议运行 scan"
|
|
307
|
-
`,
|
|
308
|
-
outputHint: '模块文档健康状态',
|
|
309
|
-
optional: false
|
|
310
|
-
},
|
|
311
|
-
{
|
|
312
|
-
name: '汇总报告',
|
|
313
|
-
prompt: `汇总前四步的所有检查结果,生成最终的自检报告。
|
|
314
|
-
|
|
315
|
-
### 输出格式
|
|
316
|
-
\`\`\`
|
|
317
|
-
🔍 SillySpec Doctor — 项目自检报告
|
|
318
|
-
|
|
319
|
-
## SillySpec 内部
|
|
320
|
-
✅ .sillyspec/ 目录结构 — 正常
|
|
321
|
-
✅ projects/*.yaml — N 个项目已注册
|
|
322
|
-
⚠️ local.yaml (xxx) — 缺少 test 命令
|
|
323
|
-
❌ sillyspec.db 阶段状态 — brainstorm 标记完成但 design.md 不存在
|
|
324
|
-
|
|
325
|
-
## 构建环境
|
|
326
|
-
✅ Node.js v23.4.0 — 可用
|
|
327
|
-
✅ npm 10.x — 可用
|
|
328
|
-
✅ Java 17.0.2 — 可用
|
|
329
|
-
❌ Maven 私服 (10.0.0.1:8081) — 不可达(超时)
|
|
330
|
-
|
|
331
|
-
## 外部依赖
|
|
332
|
-
✅ Context7 MCP — 已配置
|
|
333
|
-
⚠️ grep.app — 不可达
|
|
334
|
-
\`\`\`
|
|
335
|
-
|
|
336
|
-
### 要求
|
|
337
|
-
- 基于前 3 步的实际输出汇总,不要编造
|
|
338
|
-
- 每类问题归入对应分区
|
|
339
|
-
- 全部通过给出 🎉
|
|
340
|
-
- 如果有 ❌ 或 ⚠️,在末尾逐项给出修复建议
|
|
341
|
-
|
|
342
|
-
### 修复建议模板
|
|
343
|
-
根据问题类型给出具体可操作的修复命令:
|
|
344
|
-
|
|
345
|
-
**常见问题及修复:**
|
|
346
|
-
- CLI 未安装 → \`npm install -g sillyspec\`
|
|
347
|
-
- 缺少 local.yaml → \`sillyspec init\` 重新生成,或手动创建
|
|
348
|
-
- local.yaml 缺少 test 命令 → 补充对应命令
|
|
349
|
-
- 缺少 STACK.md → \`sillyspec run scan\` 重新扫描
|
|
350
|
-
- sillyspec.db 状态不一致 → \`sillyspec run <阶段> --reset\` 重置对应阶段
|
|
351
|
-
- 孤儿目录 → 确认后 \`rm -rf .sillyspec/changes/<目录名>\`
|
|
352
|
-
- Maven 私服不可达 → 检查 VPN、settings.xml 配置、私服状态
|
|
353
|
-
- Git remote 不可达 → 检查网络、SSH key 或凭证
|
|
354
|
-
- 工具未安装 → 给出安装命令(如 \`brew install maven\`)
|
|
355
|
-
|
|
356
|
-
每条建议格式:
|
|
357
|
-
\`\`\`
|
|
358
|
-
💡 修复:<问题描述>
|
|
359
|
-
<具体命令或操作>
|
|
360
|
-
\`\`\``,
|
|
361
|
-
outputHint: '完整自检报告',
|
|
362
|
-
optional: false
|
|
363
|
-
}
|
|
364
|
-
]
|
|
365
|
-
}
|
|
1
|
+
// SillySpec Doctor — 项目自检阶段
|
|
2
|
+
// 检查项通过 prompt 中的 bash 命令执行,此文件仅定义步骤结构
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export const definition = {
|
|
6
|
+
name: 'doctor',
|
|
7
|
+
title: '项目自检',
|
|
8
|
+
description: '检查 SillySpec 配置、构建环境和外部依赖',
|
|
9
|
+
auxiliary: true,
|
|
10
|
+
steps: [
|
|
11
|
+
{
|
|
12
|
+
name: 'SillySpec 内部检查',
|
|
13
|
+
prompt: `运行 SillySpec 内部检查。逐项执行以下命令并汇总结果:
|
|
14
|
+
|
|
15
|
+
### 1. 目录结构完整性
|
|
16
|
+
\`\`\`bash
|
|
17
|
+
# 检查 .sillyspec/ 及子目录
|
|
18
|
+
for d in .sillyspec .sillyspec/projects .sillyspec/docs .sillyspec/changes .sillyspec/.runtime; do
|
|
19
|
+
[ -d "$d" ] && echo "✅ $d" || echo "❌ $d"
|
|
20
|
+
done
|
|
21
|
+
# 检查 sillyspec.db(SQLite 权威状态源)
|
|
22
|
+
DB_FILE='.sillyspec/.runtime/sillyspec.db'
|
|
23
|
+
[ -f "$DB_FILE" ] && echo "✅ sillyspec.db 存在" || echo "❌ sillyspec.db 不存在"
|
|
24
|
+
sqlite3 "$DB_FILE" "SELECT count(*) FROM project" 2>/dev/null && echo "✅ sillyspec.db 可查询" || echo "⚠️ sillyspec.db 不可查询"
|
|
25
|
+
\`\`\`
|
|
26
|
+
|
|
27
|
+
### 2. 项目配置检查
|
|
28
|
+
\`\`\`bash
|
|
29
|
+
ls .sillyspec/projects/*.yaml 2>/dev/null
|
|
30
|
+
# 对每个 yaml 文件,检查 name 和 path 字段,验证 path 存在
|
|
31
|
+
for f in .sillyspec/projects/*.yaml; do
|
|
32
|
+
[ -f "$f" ] || continue
|
|
33
|
+
name=$(grep '^name:' "$f" | head -1 | sed 's/^name:[[:space:]]*//')
|
|
34
|
+
p=$(grep '^path:' "$f" | head -1 | sed 's/^path:[[:space:]]*//')
|
|
35
|
+
[ -z "$name" ] && echo "⚠️ $(basename $f) — 缺少 name"
|
|
36
|
+
[ -z "$p" ] && echo "⚠️ $(basename $f) — 缺少 path"
|
|
37
|
+
[ -n "$p" ] && [ ! -d "$p" ] && echo "❌ $(basename $f) — path 不存在: $p"
|
|
38
|
+
[ -n "$name" ] && [ -n "$p" ] && [ -d "$p" ] && echo "✅ $(basename $f) — $name ($p)"
|
|
39
|
+
done
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
### 3. 进度数据一致性
|
|
43
|
+
\`\`\`bash
|
|
44
|
+
# 从 sillyspec.db 读取活跃变更并检查目录存在性
|
|
45
|
+
DB_FILE='.sillyspec/.runtime/sillyspec.db'
|
|
46
|
+
if [ ! -f "$DB_FILE" ]; then echo "⚠️ sillyspec.db 不存在"; exit 0; fi
|
|
47
|
+
ACTIVE_CHANGE=$(sqlite3 "$DB_FILE" "SELECT name FROM changes WHERE status='active' ORDER BY last_active DESC LIMIT 1" 2>/dev/null)
|
|
48
|
+
if [ -z "$ACTIVE_CHANGE" ]; then echo "ℹ️ 无当前变更"; exit 0; fi
|
|
49
|
+
echo "当前变更: $ACTIVE_CHANGE"
|
|
50
|
+
DIR=".sillyspec/changes/$ACTIVE_CHANGE"
|
|
51
|
+
[ -d "$DIR" ] && echo "✅ 变更目录存在: $ACTIVE_CHANGE" || echo "❌ 变更目录不存在: $ACTIVE_CHANGE"
|
|
52
|
+
# 检查各阶段状态
|
|
53
|
+
sqlite3 -header -column "$DB_FILE" "SELECT stage, status FROM stages s JOIN changes c ON s.change_id=c.id WHERE c.name='$ACTIVE_CHANGE' ORDER BY s.stage" 2>/dev/null || echo "⚠️ 无法查询阶段数据"
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
### 4. 孤儿文件检查
|
|
57
|
+
\`\`\`bash
|
|
58
|
+
DB_FILE='.sillyspec/.runtime/sillyspec.db'
|
|
59
|
+
if [ ! -f "$DB_FILE" ]; then echo "⚠️ sillyspec.db 不存在"; exit 0; fi
|
|
60
|
+
node -e "
|
|
61
|
+
const fs = require('fs');
|
|
62
|
+
const dir = '.sillyspec/changes';
|
|
63
|
+
if (!fs.existsSync(dir)) { console.log('ℹ️ changes/ 目录不存在'); process.exit(0); }
|
|
64
|
+
const subs = fs.readdirSync(dir).filter(f => fs.statSync(dir+'/'+f).isDirectory());
|
|
65
|
+
if (subs.length === 0) { console.log('ℹ️ 无变更目录'); process.exit(0); }
|
|
66
|
+
const { execSync } = require('child_process');
|
|
67
|
+
let known;
|
|
68
|
+
try { const rows = execSync('sqlite3 -json \".sillyspec/.runtime/sillyspec.db\" \"SELECT name FROM changes WHERE status=\\\"active\\\"\"', {encoding:'utf8'}).trim(); known = new Set(JSON.parse(rows).map(r => r.name)); } catch { known = new Set(); }
|
|
69
|
+
subs.forEach(s => {
|
|
70
|
+
console.log(known.has(s) ? '✅ ' + s + ' — 已关联' : '⚠️ ' + s + ' — 孤儿目录(可清理)');
|
|
71
|
+
});
|
|
72
|
+
"
|
|
73
|
+
\`\`\`
|
|
74
|
+
|
|
75
|
+
### 5. 配置文件检查
|
|
76
|
+
\`\`\`bash
|
|
77
|
+
# 检查 local.yaml 和 STACK.md
|
|
78
|
+
for f in .sillyspec/projects/*.yaml; do
|
|
79
|
+
[ -f "$f" ] || continue
|
|
80
|
+
name=$(grep '^name:' "$f" | head -1 | sed 's/^name:[[:space:]]*//')
|
|
81
|
+
p=$(grep '^path:' "$f" | head -1 | sed 's/^path:[[:space:]]*//')
|
|
82
|
+
[ -z "$p" ] && continue
|
|
83
|
+
local_yaml="$p/.sillyspec/local.yaml"
|
|
84
|
+
stack_md="$p/.sillyspec/STACK.md"
|
|
85
|
+
[ -f "$local_yaml" ] && echo "✅ local.yaml ($name)" || echo "⚠️ local.yaml ($name) — 不存在"
|
|
86
|
+
if [ -f "$local_yaml" ]; then
|
|
87
|
+
grep -q 'test:' "$local_yaml" && echo " ✅ test 命令已配置" || echo " ⚠️ 缺少 test 命令"
|
|
88
|
+
fi
|
|
89
|
+
[ -f "$stack_md" ] && echo "✅ STACK.md ($name)" || echo "⚠️ STACK.md ($name) — 不存在"
|
|
90
|
+
done
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
### 6. Worktree 隔离环境检查
|
|
94
|
+
\`\`\`bash
|
|
95
|
+
# 检测当前目录是否在 submodule 中
|
|
96
|
+
SUPERPROJECT=$(git rev-parse --show-superproject-working-tree 2>/dev/null)
|
|
97
|
+
if [ -n "$SUPERPROJECT" ]; then
|
|
98
|
+
echo "⚠️ 当前目录在 git submodule 内,worktree 隔离不可用"
|
|
99
|
+
else
|
|
100
|
+
echo "✅ 不在 submodule 中"
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# 检测是否已在 linked worktree 中
|
|
104
|
+
GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
|
|
105
|
+
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
|
|
106
|
+
if [ "$GIT_DIR" != "$GIT_COMMON" ] && [ -z "$SUPERPROJECT" ]; then
|
|
107
|
+
echo "✅ 已在 linked worktree 中"
|
|
108
|
+
else
|
|
109
|
+
echo "ℹ️ 在主仓库中(非 worktree)"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# 检查 worktree 存储目录是否被 .gitignore 忽略
|
|
113
|
+
WT_DIR='.sillyspec/.runtime/worktrees'
|
|
114
|
+
if git check-ignore -q "$WT_DIR" 2>/dev/null; then
|
|
115
|
+
echo "✅ worktree 目录已被 .gitignore 忽略 ($WT_DIR)"
|
|
116
|
+
else
|
|
117
|
+
echo "❌ worktree 目录未被 .gitignore 忽略 ($WT_DIR) — worktree 创建将被阻断"
|
|
118
|
+
echo " 修复: 在 .gitignore 中添加 $WT_DIR/"
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# 检查 DB 中的 isolation 状态
|
|
122
|
+
DB_FILE='.sillyspec/.runtime/sillyspec.db'
|
|
123
|
+
if [ -f "$DB_FILE" ]; then
|
|
124
|
+
echo ""
|
|
125
|
+
echo "isolation 状态(来自 sillyspec.db):"
|
|
126
|
+
sqlite3 -header -column "$DB_FILE" "SELECT name, isolation_status AS status, isolation_mode AS mode, isolation_reason AS reason FROM changes WHERE status='active'" 2>/dev/null || echo "⚠️ 查询 isolation 失败"
|
|
127
|
+
else
|
|
128
|
+
echo ""
|
|
129
|
+
echo "ℹ️ sillyspec.db 不存在(尚未初始化)"
|
|
130
|
+
fi
|
|
131
|
+
else
|
|
132
|
+
echo "ℹ️ gate-status.json 不存在(尚未进入 execute 阶段)"
|
|
133
|
+
fi
|
|
134
|
+
\`\`\`\n
|
|
135
|
+
### 输出
|
|
136
|
+
汇总所有检查结果,按以下格式:
|
|
137
|
+
\`\`\`
|
|
138
|
+
## SillySpec 内部
|
|
139
|
+
✅/⚠️/❌ 各项状态
|
|
140
|
+
\`\`\`
|
|
141
|
+
|
|
142
|
+
### 注意
|
|
143
|
+
- 不要编造路径或结果,严格基于命令输出
|
|
144
|
+
- 如果 .sillyspec/ 不存在,直接输出 ❌ 并跳过后续检查`,
|
|
145
|
+
outputHint: 'SillySpec 内部检查结果',
|
|
146
|
+
optional: false
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: '构建环境检查',
|
|
150
|
+
prompt: `检查项目构建环境。先探测项目使用的构建工具,再逐项检查可用性。
|
|
151
|
+
|
|
152
|
+
### 1. 探测构建工具
|
|
153
|
+
\`\`\`bash
|
|
154
|
+
# 确定项目路径(使用 sillyspec.db 中的项目路径或当前目录)
|
|
155
|
+
PROJECT_DIR=$(sqlite3 -json '.sillyspec/.runtime/sillyspec.db' "SELECT name FROM project WHERE id=1" 2>/dev/null | node -e "const r=JSON.parse(require('fs').readFileSync(0,'utf8'));console.log(r.length>0&&r[0].name?r[0].name:'.')" 2>/dev/null || node -e "
|
|
156
|
+
const fs=require('fs');
|
|
157
|
+
try{const files=fs.readdirSync('.sillyspec/projects').filter(f=>f.endsWith('.yaml'));
|
|
158
|
+
if(files.length>0){const c=fs.readFileSync('.sillyspec/projects/'+files[0],'utf8');const m=c.match(/^path:\\s*(.+)/m);console.log(m?m[1].trim():'.')}else console.log('.')
|
|
159
|
+
}catch{console.log('.')}
|
|
160
|
+
" 2>/dev/null)
|
|
161
|
+
echo "项目目录: $PROJECT_DIR"
|
|
162
|
+
|
|
163
|
+
# 探测构建工具
|
|
164
|
+
for f in pom.xml build.gradle package.json requirements.txt pyproject.toml go.mod Cargo.toml; do
|
|
165
|
+
[ -f "$PROJECT_DIR/$f" ] && echo "检测到: $f"
|
|
166
|
+
done
|
|
167
|
+
[ -f "$PROJECT_DIR/.sillyspec/STACK.md" ] && cat "$PROJECT_DIR/.sillyspec/STACK.md" | head -30
|
|
168
|
+
\`\`\`
|
|
169
|
+
|
|
170
|
+
### 2. 构建工具可用性
|
|
171
|
+
根据上面检测到的工具,运行对应检查(未检测到的跳过):
|
|
172
|
+
|
|
173
|
+
**Maven 项目:**
|
|
174
|
+
\`\`\`bash
|
|
175
|
+
timeout 10 mvn -v 2>/dev/null | head -1 && echo "✅ Maven 可用" || echo "❌ Maven 不可用"
|
|
176
|
+
[ -f ~/.m2/settings.xml ] && echo "✅ Maven settings.xml 存在" || echo "⚠️ Maven settings.xml 不存在"
|
|
177
|
+
timeout 10 java -version 2>&1 | head -1
|
|
178
|
+
\`\`\`
|
|
179
|
+
|
|
180
|
+
**Gradle 项目:**
|
|
181
|
+
\`\`\`bash
|
|
182
|
+
timeout 10 gradle -v 2>/dev/null | head -1 && echo "✅ Gradle 可用" || echo "❌ Gradle 不可用"
|
|
183
|
+
\`\`\`
|
|
184
|
+
|
|
185
|
+
**Node.js 项目:**
|
|
186
|
+
\`\`\`bash
|
|
187
|
+
timeout 5 node -v 2>/dev/null && echo "✅ Node.js 可用" || echo "❌ Node.js 不可用"
|
|
188
|
+
timeout 5 npm -v 2>/dev/null && echo "✅ npm 可用" || echo "❌ npm 不可用"
|
|
189
|
+
timeout 5 pnpm -v 2>/dev/null && echo "✅ pnpm 可用" || echo "ℹ️ pnpm 未安装"
|
|
190
|
+
# 检查 registry
|
|
191
|
+
npm config get registry 2>/dev/null
|
|
192
|
+
\`\`\`
|
|
193
|
+
|
|
194
|
+
**Python 项目:**
|
|
195
|
+
\`\`\`bash
|
|
196
|
+
timeout 5 python3 --version 2>/dev/null && echo "✅ Python3 可用" || echo "❌ Python3 不可用"
|
|
197
|
+
timeout 5 pip3 --version 2>/dev/null && echo "✅ pip3 可用" || echo "❌ pip3 不可用"
|
|
198
|
+
\`\`\`
|
|
199
|
+
|
|
200
|
+
### 3. Maven 私服检查(仅 Maven 项目)
|
|
201
|
+
\`\`\`bash
|
|
202
|
+
# 从 settings.xml 提取仓库地址
|
|
203
|
+
if [ -f ~/.m2/settings.xml ]; then
|
|
204
|
+
grep -oP 'https?://[^<"]+:[0-9]+' ~/.m2/settings.xml 2>/dev/null | sort -u | while read url; do
|
|
205
|
+
timeout 5 curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null
|
|
206
|
+
echo " — $url"
|
|
207
|
+
done
|
|
208
|
+
fi
|
|
209
|
+
# 从 pom.xml 提取
|
|
210
|
+
if [ -f "$PROJECT_DIR/pom.xml" ]; then
|
|
211
|
+
grep -oP 'https?://[^<"]+:[0-9]+' "$PROJECT_DIR/pom.xml" 2>/dev/null | sort -u | while read url; do
|
|
212
|
+
code=$(timeout 5 curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null)
|
|
213
|
+
[ "$code" = "000" ] && echo "❌ 私服不可达: $url(超时)" || echo "✅ 私服可达 ($code): $url"
|
|
214
|
+
done
|
|
215
|
+
fi
|
|
216
|
+
\`\`\`
|
|
217
|
+
|
|
218
|
+
### 4. 运行时环境
|
|
219
|
+
\`\`\`bash
|
|
220
|
+
timeout 5 node -v 2>/dev/null && echo "Node.js: $(node -v)" || echo "❌ Node.js 未安装"
|
|
221
|
+
timeout 5 git --version 2>/dev/null && echo "Git: $(git --version)" || echo "❌ Git 未安装"
|
|
222
|
+
timeout 10 git remote -v 2>/dev/null | head -2
|
|
223
|
+
timeout 5 git ls-remote --heads origin 2>/dev/null >/dev/null && echo "✅ Git remote 可达" || echo "⚠️ Git remote 不可达"
|
|
224
|
+
timeout 5 java -version 2>&1 | head -1
|
|
225
|
+
timeout 5 python3 --version 2>/dev/null
|
|
226
|
+
\`\`\`
|
|
227
|
+
|
|
228
|
+
### 输出
|
|
229
|
+
汇总所有检查结果:
|
|
230
|
+
\`\`\`
|
|
231
|
+
## 构建环境
|
|
232
|
+
✅/⚠️/❌ 各项状态
|
|
233
|
+
\`\`\`
|
|
234
|
+
|
|
235
|
+
### 注意
|
|
236
|
+
- 未检测到的构建工具直接跳过,不要报错
|
|
237
|
+
- timeout 超时的命令视为不可用
|
|
238
|
+
- 不编造结果`,
|
|
239
|
+
outputHint: '构建环境检查结果',
|
|
240
|
+
optional: false
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: '外部依赖检查',
|
|
244
|
+
prompt: `检查外部依赖工具是否可用。
|
|
245
|
+
|
|
246
|
+
### 1. Context7 MCP
|
|
247
|
+
\`\`\`bash
|
|
248
|
+
# 检查 MCP 配置
|
|
249
|
+
for f in ~/.config/claude/claude_desktop_config.json ~/.cursor/mcp.json ~/.openclaw/mcp.json; do
|
|
250
|
+
[ -f "$f" ] && echo "MCP 配置文件: $f" && grep -i context7 "$f" 2>/dev/null && echo "✅ Context7 已配置" || true
|
|
251
|
+
done
|
|
252
|
+
# 也检查 sillyspec 自身的 setup
|
|
253
|
+
node -e "
|
|
254
|
+
try{const m=require(require('path').join(require('os').homedir(),'.sillyspec','config.json'));console.log('✅ sillyspec config 存在')}catch{console.log('ℹ️ 无 sillyspec 全局配置')}
|
|
255
|
+
" 2>/dev/null
|
|
256
|
+
\`\`\`
|
|
257
|
+
|
|
258
|
+
### 2. grep.app
|
|
259
|
+
\`\`\`bash
|
|
260
|
+
timeout 5 curl -s -o /dev/null -w "%{http_code}" https://grep.app 2>/dev/null | grep -q "200" && echo "✅ grep.app 可达" || echo "⚠️ grep.app 不可达"
|
|
261
|
+
\`\`\`
|
|
262
|
+
|
|
263
|
+
### 3. 其他 AI 工具(可选)
|
|
264
|
+
\`\`\`bash
|
|
265
|
+
# 检查常用 AI/开发工具
|
|
266
|
+
timeout 5 which gh 2>/dev/null && echo "✅ GitHub CLI 可用" || echo "ℹ️ GitHub CLI 未安装"
|
|
267
|
+
timeout 5 which docker 2>/dev/null && echo "✅ Docker 可用" || echo "ℹ️ Docker 未安装"
|
|
268
|
+
\`\`\`
|
|
269
|
+
|
|
270
|
+
### 输出
|
|
271
|
+
\`\`\`
|
|
272
|
+
## 外部依赖
|
|
273
|
+
✅/⚠️/❌ 各项状态
|
|
274
|
+
\`\`\`
|
|
275
|
+
|
|
276
|
+
### 注意
|
|
277
|
+
- 不编造结果
|
|
278
|
+
- 工具未安装用 ℹ️ 标记(非错误),不可达用 ⚠️`,
|
|
279
|
+
outputHint: '外部依赖检查结果',
|
|
280
|
+
optional: false
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: '模块文档健康检查',
|
|
284
|
+
prompt: `检查模块索引和卡片文档的健康状态。
|
|
285
|
+
|
|
286
|
+
### 操作
|
|
287
|
+
1. 运行 \`sillyspec modules status\` 查看模块索引概览
|
|
288
|
+
2. 读取 \`.sillyspec/docs/<project>/modules/_module-map.yaml\`
|
|
289
|
+
3. 对每个模块,检查:
|
|
290
|
+
- module_id 是否有对应的卡片文件(modules/<module-id>.md)
|
|
291
|
+
- 卡片文件是否有有效的 frontmatter(schema_version, doc_type, module_id)
|
|
292
|
+
- 人工备注标记是否配对(MANUAL_NOTES_START 和 MANUAL_NOTES_END 必须成对出现)
|
|
293
|
+
- needs_review 为 true 的模块列表
|
|
294
|
+
4. 汇总结果
|
|
295
|
+
|
|
296
|
+
### 输出格式
|
|
297
|
+
\`\`\`
|
|
298
|
+
📋 模块文档健康检查
|
|
299
|
+
✅ _module-map.yaml — 存在,N 个模块
|
|
300
|
+
⚠️ auth-service — needs_review=true,原因:...
|
|
301
|
+
❌ payment-service — 卡片文件缺失
|
|
302
|
+
✅ 所有模块人工备注标记配对正常
|
|
303
|
+
\`\`\`
|
|
304
|
+
|
|
305
|
+
### 注意
|
|
306
|
+
- 如果 _module-map.yaml 不存在,输出"模块索引未生成,建议运行 scan"
|
|
307
|
+
`,
|
|
308
|
+
outputHint: '模块文档健康状态',
|
|
309
|
+
optional: false
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: '汇总报告',
|
|
313
|
+
prompt: `汇总前四步的所有检查结果,生成最终的自检报告。
|
|
314
|
+
|
|
315
|
+
### 输出格式
|
|
316
|
+
\`\`\`
|
|
317
|
+
🔍 SillySpec Doctor — 项目自检报告
|
|
318
|
+
|
|
319
|
+
## SillySpec 内部
|
|
320
|
+
✅ .sillyspec/ 目录结构 — 正常
|
|
321
|
+
✅ projects/*.yaml — N 个项目已注册
|
|
322
|
+
⚠️ local.yaml (xxx) — 缺少 test 命令
|
|
323
|
+
❌ sillyspec.db 阶段状态 — brainstorm 标记完成但 design.md 不存在
|
|
324
|
+
|
|
325
|
+
## 构建环境
|
|
326
|
+
✅ Node.js v23.4.0 — 可用
|
|
327
|
+
✅ npm 10.x — 可用
|
|
328
|
+
✅ Java 17.0.2 — 可用
|
|
329
|
+
❌ Maven 私服 (10.0.0.1:8081) — 不可达(超时)
|
|
330
|
+
|
|
331
|
+
## 外部依赖
|
|
332
|
+
✅ Context7 MCP — 已配置
|
|
333
|
+
⚠️ grep.app — 不可达
|
|
334
|
+
\`\`\`
|
|
335
|
+
|
|
336
|
+
### 要求
|
|
337
|
+
- 基于前 3 步的实际输出汇总,不要编造
|
|
338
|
+
- 每类问题归入对应分区
|
|
339
|
+
- 全部通过给出 🎉
|
|
340
|
+
- 如果有 ❌ 或 ⚠️,在末尾逐项给出修复建议
|
|
341
|
+
|
|
342
|
+
### 修复建议模板
|
|
343
|
+
根据问题类型给出具体可操作的修复命令:
|
|
344
|
+
|
|
345
|
+
**常见问题及修复:**
|
|
346
|
+
- CLI 未安装 → \`npm install -g sillyspec\`
|
|
347
|
+
- 缺少 local.yaml → \`sillyspec init\` 重新生成,或手动创建
|
|
348
|
+
- local.yaml 缺少 test 命令 → 补充对应命令
|
|
349
|
+
- 缺少 STACK.md → \`sillyspec run scan\` 重新扫描
|
|
350
|
+
- sillyspec.db 状态不一致 → \`sillyspec run <阶段> --reset\` 重置对应阶段
|
|
351
|
+
- 孤儿目录 → 确认后 \`rm -rf .sillyspec/changes/<目录名>\`
|
|
352
|
+
- Maven 私服不可达 → 检查 VPN、settings.xml 配置、私服状态
|
|
353
|
+
- Git remote 不可达 → 检查网络、SSH key 或凭证
|
|
354
|
+
- 工具未安装 → 给出安装命令(如 \`brew install maven\`)
|
|
355
|
+
|
|
356
|
+
每条建议格式:
|
|
357
|
+
\`\`\`
|
|
358
|
+
💡 修复:<问题描述>
|
|
359
|
+
<具体命令或操作>
|
|
360
|
+
\`\`\``,
|
|
361
|
+
outputHint: '完整自检报告',
|
|
362
|
+
optional: false
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
}
|