sillyspec 3.7.14 → 3.7.16
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 +77 -0
- package/.claude/skills/sillyspec-brainstorm/SKILL.md +591 -0
- package/.claude/skills/sillyspec-continue/SKILL.md +44 -0
- package/.claude/skills/sillyspec-execute/SKILL.md +233 -0
- package/.claude/skills/sillyspec-explore/SKILL.md +96 -0
- package/.claude/skills/sillyspec-export/SKILL.md +53 -0
- package/.claude/skills/sillyspec-init/SKILL.md +171 -0
- package/.claude/skills/sillyspec-plan/SKILL.md +263 -0
- package/.claude/skills/sillyspec-propose/SKILL.md +248 -0
- package/.claude/skills/sillyspec-quick/SKILL.md +102 -0
- package/.claude/skills/sillyspec-resume/SKILL.md +111 -0
- package/{templates/scan.md → .claude/skills/sillyspec-scan/SKILL.md} +22 -60
- package/.claude/skills/sillyspec-state/SKILL.md +54 -0
- package/.claude/skills/sillyspec-status/SKILL.md +131 -0
- package/.claude/skills/sillyspec-verify/SKILL.md +146 -0
- package/.claude/skills/sillyspec-workspace/SKILL.md +149 -0
- package/.sillyspec/changes/run-command-design/design.md +1230 -0
- package/.sillyspec/docs/sillyspec/scan/.gitkeep +0 -0
- package/.sillyspec/knowledge/INDEX.md +8 -0
- package/.sillyspec/knowledge/uncategorized.md +3 -0
- package/.sillyspec/projects/sillyspec.yaml +3 -0
- package/package.json +1 -1
- package/packages/dashboard/dist/assets/index-Bx0cgoK_.js +7446 -0
- package/packages/dashboard/dist/assets/index-DbkUSsNO.css +1 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package-lock.json +220 -0
- package/packages/dashboard/package.json +8 -5
- package/packages/dashboard/server/index.js +91 -3
- package/packages/dashboard/server/parser.js +252 -28
- package/packages/dashboard/src/App.vue +54 -8
- package/packages/dashboard/src/components/ActionBar.vue +23 -39
- package/packages/dashboard/src/components/CommandPalette.vue +40 -65
- package/packages/dashboard/src/components/DetailPanel.vue +68 -53
- package/packages/dashboard/src/components/DocPreview.vue +137 -20
- package/packages/dashboard/src/components/DocTree.vue +48 -26
- package/packages/dashboard/src/components/LogStream.vue +12 -32
- package/packages/dashboard/src/components/PipelineStage.vue +8 -8
- package/packages/dashboard/src/components/PipelineView.vue +35 -43
- package/packages/dashboard/src/components/ProjectList.vue +51 -77
- package/packages/dashboard/src/components/ProjectOverview.vue +178 -0
- package/packages/dashboard/src/components/StageBadge.vue +13 -13
- package/packages/dashboard/src/components/StepCard.vue +11 -11
- package/packages/dashboard/src/components/detail/DocsDetail.vue +48 -0
- package/packages/dashboard/src/components/detail/GitDetail.vue +61 -0
- package/packages/dashboard/src/components/detail/TechDetail.vue +43 -0
- package/packages/dashboard/src/main.js +4 -1
- package/packages/dashboard/src/style.css +14 -14
- package/src/index.js +55 -8
- package/src/init.js +69 -196
- package/src/migrate.js +1 -18
- package/src/progress.js +279 -281
- package/src/run.js +320 -0
- package/src/setup.js +1 -9
- package/src/stages/brainstorm.js +210 -0
- package/src/stages/execute.js +190 -0
- package/src/stages/index.js +22 -0
- package/src/stages/plan.js +118 -0
- package/src/stages/propose.js +115 -0
- package/src/stages/verify.js +98 -0
- package/packages/dashboard/dist/assets/index-hNnQCobe.css +0 -1
- package/packages/dashboard/dist/assets/index-qgPzQGjk.js +0 -17
- package/templates/archive.md +0 -121
- package/templates/brainstorm.md +0 -246
- package/templates/commit.md +0 -123
- package/templates/continue.md +0 -32
- package/templates/execute.md +0 -314
- package/templates/explore.md +0 -60
- package/templates/export.md +0 -21
- package/templates/init.md +0 -61
- package/templates/plan.md +0 -157
- package/templates/progress-format.md +0 -90
- package/templates/propose.md +0 -73
- package/templates/quick.md +0 -135
- package/templates/resume-dialog.md +0 -55
- package/templates/resume.md +0 -53
- package/templates/scan-quick.md +0 -49
- package/templates/skills/playwright-e2e/SKILL.md +0 -340
- package/templates/status.md +0 -72
- package/templates/verify.md +0 -253
- package/templates/workspace-sync.md +0 -89
- package/templates/workspace.md +0 -67
- /package/.sillyspec/{docs/sillyspec/brainstorm → changes/brainstorm-archive}/2026-04-05-dashboard-design.md +0 -0
- /package/.sillyspec/{docs/sillyspec/brainstorm → changes/brainstorm-archive}/2026-04-05-unified-docs-design.md +0 -0
- /package/.sillyspec/{specs/2026-04-05-dashboard-design.md → changes/dashboard/design.md.braindraft} +0 -0
- /package/.sillyspec/{specs/2026-04-05-unified-docs-design.md → changes/unified-docs-design/design.md} +0 -0
package/src/init.js
CHANGED
|
@@ -1,56 +1,31 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync,
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, statSync } from 'fs';
|
|
2
2
|
import { join, resolve, dirname, basename } from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
import { checkbox, select, confirm, input } from '@inquirer/prompts';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
|
-
import ora from 'ora';
|
|
8
7
|
|
|
9
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
9
|
const __dirname = dirname(__filename);
|
|
11
|
-
|
|
10
|
+
|
|
11
|
+
// ── 递归复制目录 ──
|
|
12
|
+
function copyDirSync(src, dst) {
|
|
13
|
+
mkdirSync(dst, { recursive: true });
|
|
14
|
+
for (const entry of readdirSync(src, { withFileTypes: true })) {
|
|
15
|
+
if (entry.name === 'node_modules' || entry.name === '.git') continue;
|
|
16
|
+
const srcPath = join(src, entry.name);
|
|
17
|
+
const dstPath = join(dst, entry.name);
|
|
18
|
+
if (entry.isDirectory()) {
|
|
19
|
+
copyDirSync(srcPath, dstPath);
|
|
20
|
+
} else if (entry.name.endsWith('.md')) {
|
|
21
|
+
writeFileSync(dstPath, readFileSync(srcPath));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
12
25
|
|
|
13
26
|
// ── 元数据映射 ──
|
|
14
27
|
|
|
15
|
-
const DESCRIPTIONS = {
|
|
16
|
-
init: '绿地项目初始化 — 深度提问、调研、需求文档、路线图',
|
|
17
|
-
scan: '代码库扫描 — 支持快速扫描和深度扫描两阶段',
|
|
18
|
-
explore: '自由思考模式 — 讨论、画图、调研,不写代码',
|
|
19
|
-
brainstorm: '需求探索 — 结构化头脑风暴,生成设计文档(创建性工作前必用)',
|
|
20
|
-
propose: '生成结构化规范 — proposal + design + tasks',
|
|
21
|
-
plan: '编写实现计划 — 2-5 分钟粒度,精确到文件路径和代码',
|
|
22
|
-
execute: '波次执行 — 子代理并行 + 强制 TDD + 两阶段审查',
|
|
23
|
-
verify: '验证实现 — 对照规范检查 + 测试套件',
|
|
24
|
-
archive: '归档变更 — 规范沉淀,可追溯',
|
|
25
|
-
commit: '智能提交 — 自动收集变更信息,生成 commit message',
|
|
26
|
-
status: '查看项目进度和状态',
|
|
27
|
-
continue: '自动判断并执行下一步',
|
|
28
|
-
state: '查看当前工作状态 — 显示 STATE.md 内容',
|
|
29
|
-
resume: '恢复工作 — 从中断处继续',
|
|
30
|
-
quick: '快速任务 — 跳过完整流程,直接做',
|
|
31
|
-
workspace: '工作区管理 — 初始化、管理多项目工作区,查看子项目状态',
|
|
32
|
-
export: '导出成功方案为可复用模板',
|
|
33
|
-
};
|
|
34
28
|
|
|
35
|
-
const ARG_HINTS = {
|
|
36
|
-
init: '[项目名]',
|
|
37
|
-
scan: '[可选:指定区域,如 \'api\' 或 \'auth\'] [--deep 深度扫描]',
|
|
38
|
-
explore: '[探索主题]',
|
|
39
|
-
brainstorm: '[需求或想法描述]',
|
|
40
|
-
propose: '[变更名]',
|
|
41
|
-
plan: '[计划名]',
|
|
42
|
-
execute: '[任务编号或 \'all\']',
|
|
43
|
-
verify: '[可选:指定验证范围]',
|
|
44
|
-
archive: '[变更名]',
|
|
45
|
-
commit: '[可选:自定义 commit message]',
|
|
46
|
-
status: '',
|
|
47
|
-
continue: '',
|
|
48
|
-
state: '[可选备注]',
|
|
49
|
-
resume: '',
|
|
50
|
-
quick: '[任务描述]',
|
|
51
|
-
workspace: '[可选:add/remove/status/info]',
|
|
52
|
-
export: '<change-name> [--to <path>]',
|
|
53
|
-
};
|
|
54
29
|
|
|
55
30
|
const VALID_TOOLS = ['claude', 'claude_skills', 'cursor', 'openclaw', 'codex', 'gemini', 'opencode'];
|
|
56
31
|
|
|
@@ -64,10 +39,6 @@ const TOOL_LABELS = {
|
|
|
64
39
|
opencode: 'OpenCode (通过 INSTRUCTIONS.md)',
|
|
65
40
|
};
|
|
66
41
|
|
|
67
|
-
// Slash commands 工具:安装 markdown 模板命令
|
|
68
|
-
const SLASH_COMMAND_TOOLS = ['claude', 'claude_skills', 'cursor', 'openclaw'];
|
|
69
|
-
|
|
70
|
-
// 指令文件工具:注入规范引用到指令文件
|
|
71
42
|
const INSTRUCTION_TOOLS = ['codex', 'gemini', 'opencode'];
|
|
72
43
|
|
|
73
44
|
const INSTRUCTION_FILE_MAP = {
|
|
@@ -86,78 +57,11 @@ const INJECTION_CONTENT = `## SillySpec — 规范驱动开发
|
|
|
86
57
|
- 遵循 \`.sillyspec/docs/<project>/scan/CONVENTIONS.md\` 中的代码风格
|
|
87
58
|
|
|
88
59
|
### 工作流程
|
|
89
|
-
- 读取 \`.sillyspec/
|
|
90
|
-
- 各阶段产出文件位于 \`.sillyspec/
|
|
91
|
-
- 详细流程参考模板文件:\`.sillyspec/.templates/\`(brainstorm.md, plan.md, execute.md 等)
|
|
60
|
+
- 读取 \`.sillyspec/.runtime/progress.json\` 确认当前阶段(使用 \`sillyspec progress show\`)
|
|
61
|
+
- 各阶段产出文件位于 \`.sillyspec/changes/<变更名>/\` 下
|
|
92
62
|
`;
|
|
93
63
|
|
|
94
|
-
// ──
|
|
95
|
-
|
|
96
|
-
function generateClaude(projectDir, name, desc, body, argHint, version) {
|
|
97
|
-
const outDir = join(projectDir, '.claude', 'commands', 'sillyspec');
|
|
98
|
-
mkdirSync(outDir, { recursive: true });
|
|
99
|
-
writeFileSync(join(outDir, `${name}.md`),
|
|
100
|
-
`---
|
|
101
|
-
description: ${desc}
|
|
102
|
-
argument-hint: "${argHint}"
|
|
103
|
-
version: "${version}"
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
${body}`
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function generateClaudeSkills(projectDir, name, desc, body, argHint, version) {
|
|
111
|
-
const outDir = join(projectDir, '.claude', 'skills', `sillyspec-${name}`);
|
|
112
|
-
mkdirSync(outDir, { recursive: true });
|
|
113
|
-
writeFileSync(join(outDir, 'SKILL.md'),
|
|
114
|
-
`---
|
|
115
|
-
name: sillyspec:${name}
|
|
116
|
-
description: ${desc}
|
|
117
|
-
version: "${version}"
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
${body}`
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function generateCursor(projectDir, name, desc, body, argHint, version) {
|
|
125
|
-
const outDir = join(projectDir, '.cursor', 'commands');
|
|
126
|
-
mkdirSync(outDir, { recursive: true });
|
|
127
|
-
writeFileSync(join(outDir, `sillyspec-${name}.md`),
|
|
128
|
-
`---
|
|
129
|
-
name: /sillyspec-${name}
|
|
130
|
-
id: sillyspec-${name}
|
|
131
|
-
description: ${desc}
|
|
132
|
-
version: "${version}"
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
${body}`
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function generateOpenclaw(projectDir, name, desc, body, argHint, version) {
|
|
140
|
-
const outDir = join(projectDir, '.openclaw', 'skills', `sillyspec-${name}`);
|
|
141
|
-
mkdirSync(outDir, { recursive: true });
|
|
142
|
-
writeFileSync(join(outDir, 'SKILL.md'),
|
|
143
|
-
`---
|
|
144
|
-
name: sillyspec:${name}
|
|
145
|
-
description: ${desc}
|
|
146
|
-
version: "${version}"
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
${body}`
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const GENERATORS = {
|
|
154
|
-
claude: generateClaude,
|
|
155
|
-
claude_skills: generateClaudeSkills,
|
|
156
|
-
cursor: generateCursor,
|
|
157
|
-
openclaw: generateOpenclaw,
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
// ── 指令文件注入 ──
|
|
64
|
+
// ── 注入指令文件 ──
|
|
161
65
|
|
|
162
66
|
function injectInstructions(tool, projectDir) {
|
|
163
67
|
const fileName = INSTRUCTION_FILE_MAP[tool];
|
|
@@ -217,14 +121,11 @@ async function doInstall(projectDir, tools, isWorkspace, subprojects = []) {
|
|
|
217
121
|
writeFileSync(projectYamlPath, `name: ${projectName}\npath: .\nstatus: active\n`);
|
|
218
122
|
}
|
|
219
123
|
|
|
220
|
-
// 创建 docs/<projectName>/
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const gitkeepPath = join(subDir, '.gitkeep');
|
|
226
|
-
if (!existsSync(gitkeepPath)) writeFileSync(gitkeepPath, '');
|
|
227
|
-
}
|
|
124
|
+
// 创建 docs/<projectName>/scan/ 子目录(代码扫描结果)
|
|
125
|
+
const scanDir = join(projectDir, '.sillyspec', 'docs', projectName, 'scan');
|
|
126
|
+
mkdirSync(scanDir, { recursive: true });
|
|
127
|
+
const gitkeepPath = join(scanDir, '.gitkeep');
|
|
128
|
+
if (!existsSync(gitkeepPath)) writeFileSync(gitkeepPath, '');
|
|
228
129
|
|
|
229
130
|
// 兼容:保留旧的 codebase/ changes/ quicklog/ 目录(如果已存在不删除)
|
|
230
131
|
if (isWorkspace) {
|
|
@@ -250,13 +151,22 @@ async function doInstall(projectDir, tools, isWorkspace, subprojects = []) {
|
|
|
250
151
|
mkdirSync(join(runtimeDir, sub), { recursive: true });
|
|
251
152
|
}
|
|
252
153
|
|
|
253
|
-
//
|
|
254
|
-
const
|
|
255
|
-
if (existsSync(
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
154
|
+
// 创建初始 progress.json
|
|
155
|
+
const progressPath = join(runtimeDir, 'progress.json');
|
|
156
|
+
if (!existsSync(progressPath)) {
|
|
157
|
+
const initialProgress = {
|
|
158
|
+
project: projectName,
|
|
159
|
+
currentStage: '',
|
|
160
|
+
stages: {
|
|
161
|
+
brainstorm: { status: 'pending', steps: [], startedAt: null, completedAt: null },
|
|
162
|
+
propose: { status: 'pending', steps: [], startedAt: null, completedAt: null },
|
|
163
|
+
plan: { status: 'pending', steps: [], startedAt: null, completedAt: null },
|
|
164
|
+
execute: { status: 'pending', steps: [], startedAt: null, completedAt: null },
|
|
165
|
+
verify: { status: 'pending', steps: [], startedAt: null, completedAt: null }
|
|
166
|
+
},
|
|
167
|
+
lastActive: null
|
|
168
|
+
};
|
|
169
|
+
writeFileSync(progressPath, JSON.stringify(initialProgress, null, 2) + '\n');
|
|
260
170
|
}
|
|
261
171
|
|
|
262
172
|
// 创建初始 user-inputs.md
|
|
@@ -266,7 +176,7 @@ async function doInstall(projectDir, tools, isWorkspace, subprojects = []) {
|
|
|
266
176
|
}
|
|
267
177
|
|
|
268
178
|
const gitignorePath = join(projectDir, '.gitignore');
|
|
269
|
-
const ignoreRules = ['.sillyspec/
|
|
179
|
+
const ignoreRules = ['.sillyspec/codebase/SCAN-RAW.md', '.sillyspec/local.yaml', '.sillyspec/.runtime/'];
|
|
270
180
|
if (existsSync(gitignorePath)) {
|
|
271
181
|
const content = readFileSync(gitignorePath, 'utf8');
|
|
272
182
|
let updated = content.trimEnd();
|
|
@@ -280,57 +190,34 @@ async function doInstall(projectDir, tools, isWorkspace, subprojects = []) {
|
|
|
280
190
|
writeFileSync(gitignorePath, ignoreRules.join('\n') + '\n');
|
|
281
191
|
}
|
|
282
192
|
|
|
283
|
-
//
|
|
284
|
-
const templateFiles = readdirSync(TEMPLATE_DIR).filter(f => f.endsWith('.md'));
|
|
285
|
-
let count = 0;
|
|
286
|
-
|
|
193
|
+
// 注入指令文件(codex/gemini/opencode)
|
|
287
194
|
for (let i = 0; i < tools.length; i++) {
|
|
288
195
|
const toolName = tools[i];
|
|
289
|
-
const label = TOOL_LABELS[toolName] || toolName;
|
|
290
|
-
|
|
291
196
|
if (INSTRUCTION_TOOLS.includes(toolName)) {
|
|
292
|
-
|
|
293
|
-
try {
|
|
294
|
-
injectInstructions(toolName, projectDir);
|
|
295
|
-
// 复制模板文件到 .sillyspec/.templates/
|
|
296
|
-
const templatesSourceDir = join(TEMPLATE_DIR);
|
|
297
|
-
const templatesDir = join(projectDir, '.sillyspec', '.templates');
|
|
298
|
-
if (!existsSync(templatesDir)) {
|
|
299
|
-
mkdirSync(templatesDir, { recursive: true });
|
|
300
|
-
for (const file of readdirSync(templatesSourceDir)) {
|
|
301
|
-
if (file.endsWith('.md')) {
|
|
302
|
-
copyFileSync(join(templatesSourceDir, file), join(templatesDir, file));
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
spinner.succeed(`${label} 完成`);
|
|
307
|
-
count++;
|
|
308
|
-
} catch (err) {
|
|
309
|
-
spinner.fail(`${label} 失败: ${err.message}`);
|
|
310
|
-
throw err;
|
|
311
|
-
}
|
|
312
|
-
continue;
|
|
197
|
+
injectInstructions(toolName, projectDir);
|
|
313
198
|
}
|
|
199
|
+
}
|
|
314
200
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
201
|
+
// 复制 skills 到 .claude/skills/(给 Claude Code 使用)
|
|
202
|
+
const claudeSkillsDir = join(projectDir, '.claude', 'skills');
|
|
203
|
+
// 优先从 npm 包自带位置复制,其次从 ~/.agents/skills/
|
|
204
|
+
const npmSkillsDir = join(__dirname, '..', '.claude', 'skills');
|
|
205
|
+
const localSkillsDir = join(homedir(), '.agents', 'skills');
|
|
206
|
+
const skillsSource = existsSync(npmSkillsDir) ? npmSkillsDir : existsSync(localSkillsDir) ? localSkillsDir : null;
|
|
207
|
+
if (skillsSource) {
|
|
208
|
+
const sillyspecSkills = readdirSync(skillsSource).filter(f => f.startsWith('sillyspec-') && statSync(join(skillsSource, f)).isDirectory());
|
|
209
|
+
if (sillyspecSkills.length > 0) {
|
|
210
|
+
mkdirSync(claudeSkillsDir, { recursive: true });
|
|
211
|
+
for (const skill of sillyspecSkills) {
|
|
212
|
+
copyDirSync(join(skillsSource, skill), join(claudeSkillsDir, skill));
|
|
326
213
|
}
|
|
327
|
-
|
|
328
|
-
} catch (err) {
|
|
329
|
-
spinner.fail(`${label} 失败: ${err.message}`);
|
|
330
|
-
throw err;
|
|
214
|
+
console.log(chalk.green(' ✓ Claude Code skills 已同步 (' + sillyspecSkills.length + ' 个)'));
|
|
331
215
|
}
|
|
216
|
+
} else {
|
|
217
|
+
console.log(chalk.yellow(' ⚠ 未找到 skills 目录,跳过 Claude Code skills 同步'));
|
|
332
218
|
}
|
|
333
219
|
|
|
220
|
+
|
|
334
221
|
// 工作区配置
|
|
335
222
|
if (isWorkspace) {
|
|
336
223
|
const configPath = join(projectDir, '.sillyspec', 'config.yaml');
|
|
@@ -354,13 +241,11 @@ shared: []
|
|
|
354
241
|
);
|
|
355
242
|
}
|
|
356
243
|
}
|
|
357
|
-
|
|
358
|
-
return count;
|
|
359
244
|
}
|
|
360
245
|
|
|
361
246
|
// ── 安装完成总结 ──
|
|
362
247
|
|
|
363
|
-
function showSummary(version, tools, isWorkspace
|
|
248
|
+
function showSummary(version, tools, isWorkspace) {
|
|
364
249
|
const toolLabels = tools.map(t => TOOL_LABELS[t] || t);
|
|
365
250
|
const mode = isWorkspace ? '多项目工作区' : '单项目';
|
|
366
251
|
|
|
@@ -371,19 +256,13 @@ function showSummary(version, tools, isWorkspace, count) {
|
|
|
371
256
|
console.log('');
|
|
372
257
|
console.log(` 已安装工具: ${chalk.cyan(toolLabels.join(', '))}`);
|
|
373
258
|
console.log(` 模式: ${chalk.yellow(mode)}`);
|
|
374
|
-
console.log('');
|
|
375
|
-
console.log(` 📄 ${count} 个命令已就绪`);
|
|
376
259
|
console.log(' 📁 .sillyspec/ — 项目规范目录');
|
|
377
260
|
console.log('');
|
|
378
|
-
console.log('
|
|
379
|
-
console.log('
|
|
380
|
-
console.log('
|
|
381
|
-
console.log(' 自由思考:' + chalk.bold('/sillyspec:explore "你的想法"'));
|
|
382
|
-
console.log('');
|
|
383
|
-
console.log(chalk.gray(' 重启你的 AI 工具以使 slash commands 生效。'));
|
|
261
|
+
console.log(' 下一步:使用 AI 技能开始工作');
|
|
262
|
+
console.log(' OpenClaw: ' + chalk.bold('/sillyspec:brainstorm'));
|
|
263
|
+
console.log(' Claude Code: ' + chalk.bold('/sillyspec:brainstorm'));
|
|
384
264
|
console.log('');
|
|
385
265
|
console.log(chalk.dim(' 💡 推荐安装 MCP 工具增强 AI 能力:sillyspec setup'));
|
|
386
|
-
console.log(chalk.dim(' Context7 — 查最新文档 | grep.app — 搜开源实现 | Chrome DevTools — 浏览器自动化'));
|
|
387
266
|
console.log('');
|
|
388
267
|
}
|
|
389
268
|
|
|
@@ -510,7 +389,7 @@ export async function cmdInit(projectDir, options = {}) {
|
|
|
510
389
|
|
|
511
390
|
console.log('');
|
|
512
391
|
const count = await doInstall(projectDir, selectedTools, isWorkspace, subprojects);
|
|
513
|
-
showSummary(version, selectedTools, isWorkspace
|
|
392
|
+
showSummary(version, selectedTools, isWorkspace);
|
|
514
393
|
return;
|
|
515
394
|
}
|
|
516
395
|
|
|
@@ -528,23 +407,17 @@ export async function cmdInit(projectDir, options = {}) {
|
|
|
528
407
|
tools = detectTools(projectDir);
|
|
529
408
|
}
|
|
530
409
|
|
|
531
|
-
|
|
410
|
+
await doInstall(projectDir, tools, !!workspace);
|
|
532
411
|
|
|
533
412
|
console.log('');
|
|
534
413
|
console.log(chalk.green(` ✅ SillySpec v${version} 安装完成!`));
|
|
535
414
|
console.log('');
|
|
536
|
-
console.log(` 📄 ${count} 个命令已就绪`);
|
|
537
415
|
console.log(' 📁 .sillyspec/ — 项目规范目录');
|
|
538
416
|
console.log('');
|
|
539
|
-
console.log('
|
|
540
|
-
console.log(`
|
|
541
|
-
console.log(`
|
|
542
|
-
console.log(` 自由探索 → ${chalk.bold('/sillyspec:explore "你的想法"')}`);
|
|
543
|
-
if (workspace) {
|
|
544
|
-
console.log(` 管理子项目 → ${chalk.bold('/sillyspec:workspace add')}`);
|
|
545
|
-
}
|
|
417
|
+
console.log(' 下一步:使用 AI 技能开始工作');
|
|
418
|
+
console.log(` OpenClaw: ${chalk.bold('/sillyspec:brainstorm')}`);
|
|
419
|
+
console.log(` Claude Code: ${chalk.bold('/sillyspec:brainstorm')}`);
|
|
546
420
|
console.log('');
|
|
547
421
|
console.log(chalk.dim(' 💡 增强能力:sillyspec setup(安装 MCP 工具)'));
|
|
548
|
-
console.log(chalk.dim(' 💡 完整配置:sillyspec init --interactive'));
|
|
549
422
|
console.log('');
|
|
550
423
|
}
|
package/src/migrate.js
CHANGED
|
@@ -48,24 +48,7 @@ export function migrateDocs(projectDir) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
// 2. specs/
|
|
52
|
-
const specsDir = join(sillyspecDir, 'specs');
|
|
53
|
-
if (existsSync(specsDir)) {
|
|
54
|
-
const targetDir = join(docsBase, 'brainstorm');
|
|
55
|
-
mkdirSync(targetDir, { recursive: true });
|
|
56
|
-
const files = readdirSync(specsDir).filter(f => f.endsWith('.md'));
|
|
57
|
-
for (const file of files) {
|
|
58
|
-
const src = join(specsDir, file);
|
|
59
|
-
const dest = join(targetDir, file);
|
|
60
|
-
if (!existsSync(dest)) {
|
|
61
|
-
copyFileSync(src, dest);
|
|
62
|
-
console.log(chalk.green(' ✅') + ` brainstorm/${file}`);
|
|
63
|
-
migrated++;
|
|
64
|
-
} else {
|
|
65
|
-
console.log(chalk.yellow(' ⏭️') + ` brainstorm/${file} (已存在)`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
51
|
+
// 2. specs/ is deprecated — designs live in changes/<变更名>/design.md
|
|
69
52
|
|
|
70
53
|
// 3. changes/archive/ → docs/<project>/archive/
|
|
71
54
|
const archiveDir = join(sillyspecDir, 'changes', 'archive');
|