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.
Files changed (85) hide show
  1. package/.claude/skills/sillyspec-archive/SKILL.md +77 -0
  2. package/.claude/skills/sillyspec-brainstorm/SKILL.md +591 -0
  3. package/.claude/skills/sillyspec-continue/SKILL.md +44 -0
  4. package/.claude/skills/sillyspec-execute/SKILL.md +233 -0
  5. package/.claude/skills/sillyspec-explore/SKILL.md +96 -0
  6. package/.claude/skills/sillyspec-export/SKILL.md +53 -0
  7. package/.claude/skills/sillyspec-init/SKILL.md +171 -0
  8. package/.claude/skills/sillyspec-plan/SKILL.md +263 -0
  9. package/.claude/skills/sillyspec-propose/SKILL.md +248 -0
  10. package/.claude/skills/sillyspec-quick/SKILL.md +102 -0
  11. package/.claude/skills/sillyspec-resume/SKILL.md +111 -0
  12. package/{templates/scan.md → .claude/skills/sillyspec-scan/SKILL.md} +22 -60
  13. package/.claude/skills/sillyspec-state/SKILL.md +54 -0
  14. package/.claude/skills/sillyspec-status/SKILL.md +131 -0
  15. package/.claude/skills/sillyspec-verify/SKILL.md +146 -0
  16. package/.claude/skills/sillyspec-workspace/SKILL.md +149 -0
  17. package/.sillyspec/changes/run-command-design/design.md +1230 -0
  18. package/.sillyspec/docs/sillyspec/scan/.gitkeep +0 -0
  19. package/.sillyspec/knowledge/INDEX.md +8 -0
  20. package/.sillyspec/knowledge/uncategorized.md +3 -0
  21. package/.sillyspec/projects/sillyspec.yaml +3 -0
  22. package/package.json +1 -1
  23. package/packages/dashboard/dist/assets/index-Bx0cgoK_.js +7446 -0
  24. package/packages/dashboard/dist/assets/index-DbkUSsNO.css +1 -0
  25. package/packages/dashboard/dist/index.html +2 -2
  26. package/packages/dashboard/package-lock.json +220 -0
  27. package/packages/dashboard/package.json +8 -5
  28. package/packages/dashboard/server/index.js +91 -3
  29. package/packages/dashboard/server/parser.js +252 -28
  30. package/packages/dashboard/src/App.vue +54 -8
  31. package/packages/dashboard/src/components/ActionBar.vue +23 -39
  32. package/packages/dashboard/src/components/CommandPalette.vue +40 -65
  33. package/packages/dashboard/src/components/DetailPanel.vue +68 -53
  34. package/packages/dashboard/src/components/DocPreview.vue +137 -20
  35. package/packages/dashboard/src/components/DocTree.vue +48 -26
  36. package/packages/dashboard/src/components/LogStream.vue +12 -32
  37. package/packages/dashboard/src/components/PipelineStage.vue +8 -8
  38. package/packages/dashboard/src/components/PipelineView.vue +35 -43
  39. package/packages/dashboard/src/components/ProjectList.vue +51 -77
  40. package/packages/dashboard/src/components/ProjectOverview.vue +178 -0
  41. package/packages/dashboard/src/components/StageBadge.vue +13 -13
  42. package/packages/dashboard/src/components/StepCard.vue +11 -11
  43. package/packages/dashboard/src/components/detail/DocsDetail.vue +48 -0
  44. package/packages/dashboard/src/components/detail/GitDetail.vue +61 -0
  45. package/packages/dashboard/src/components/detail/TechDetail.vue +43 -0
  46. package/packages/dashboard/src/main.js +4 -1
  47. package/packages/dashboard/src/style.css +14 -14
  48. package/src/index.js +55 -8
  49. package/src/init.js +69 -196
  50. package/src/migrate.js +1 -18
  51. package/src/progress.js +279 -281
  52. package/src/run.js +320 -0
  53. package/src/setup.js +1 -9
  54. package/src/stages/brainstorm.js +210 -0
  55. package/src/stages/execute.js +190 -0
  56. package/src/stages/index.js +22 -0
  57. package/src/stages/plan.js +118 -0
  58. package/src/stages/propose.js +115 -0
  59. package/src/stages/verify.js +98 -0
  60. package/packages/dashboard/dist/assets/index-hNnQCobe.css +0 -1
  61. package/packages/dashboard/dist/assets/index-qgPzQGjk.js +0 -17
  62. package/templates/archive.md +0 -121
  63. package/templates/brainstorm.md +0 -246
  64. package/templates/commit.md +0 -123
  65. package/templates/continue.md +0 -32
  66. package/templates/execute.md +0 -314
  67. package/templates/explore.md +0 -60
  68. package/templates/export.md +0 -21
  69. package/templates/init.md +0 -61
  70. package/templates/plan.md +0 -157
  71. package/templates/progress-format.md +0 -90
  72. package/templates/propose.md +0 -73
  73. package/templates/quick.md +0 -135
  74. package/templates/resume-dialog.md +0 -55
  75. package/templates/resume.md +0 -53
  76. package/templates/scan-quick.md +0 -49
  77. package/templates/skills/playwright-e2e/SKILL.md +0 -340
  78. package/templates/status.md +0 -72
  79. package/templates/verify.md +0 -253
  80. package/templates/workspace-sync.md +0 -89
  81. package/templates/workspace.md +0 -67
  82. /package/.sillyspec/{docs/sillyspec/brainstorm → changes/brainstorm-archive}/2026-04-05-dashboard-design.md +0 -0
  83. /package/.sillyspec/{docs/sillyspec/brainstorm → changes/brainstorm-archive}/2026-04-05-unified-docs-design.md +0 -0
  84. /package/.sillyspec/{specs/2026-04-05-dashboard-design.md → changes/dashboard/design.md.braindraft} +0 -0
  85. /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, copyFileSync } from 'fs';
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
- const TEMPLATE_DIR = resolve(__dirname, '..', 'templates');
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/STATE.md\` 确认当前阶段
90
- - 各阶段产出文件位于 \`.sillyspec/docs/<project>/changes/<变更名>/\` 下
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 docsBase = join(projectDir, '.sillyspec', 'docs', projectName);
222
- for (const sub of ['scan', 'brainstorm', 'plan', 'changes', 'archive', 'quicklog']) {
223
- const subDir = join(docsBase, sub);
224
- mkdirSync(subDir, { recursive: true });
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
- // 复制 resume-dialog.md 到 .runtime/templates/
254
- const resumeDialogSrc = join(TEMPLATE_DIR, 'resume-dialog.md');
255
- if (existsSync(resumeDialogSrc)) {
256
- const dest = join(runtimeDir, 'templates', 'resume-dialog.md');
257
- if (!existsSync(dest)) {
258
- copyFileSync(resumeDialogSrc, dest);
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/STATE.md', '.sillyspec/codebase/SCAN-RAW.md', '.sillyspec/local.yaml', '.sillyspec/.runtime/'];
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
- // 生成 slash command 文件
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
- const spinner = ora(`安装 ${label}... (${i + 1}/${tools.length})`).start();
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
- const spinner = ora(`安装 ${label}... (${i + 1}/${tools.length})`).start();
316
- try {
317
- const gen = GENERATORS[toolName];
318
- const ver = getVersion();
319
- for (const file of templateFiles) {
320
- const name = file.replace('.md', '');
321
- const desc = DESCRIPTIONS[name] || `SillySpec ${name}`;
322
- const argHint = ARG_HINTS[name] || '';
323
- const body = readFileSync(join(TEMPLATE_DIR, file), 'utf8');
324
- gen(projectDir, name, desc, body, argHint, ver);
325
- count++;
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
- spinner.succeed(`${label} 完成`);
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, count) {
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(' 全新项目:' + chalk.bold('/sillyspec:init'));
380
- console.log(' 已有代码:' + chalk.bold('/sillyspec:scan'));
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, count);
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
- const count = await doInstall(projectDir, tools, !!workspace);
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(` 全新项目 → ${chalk.bold('/sillyspec:init')}`);
541
- console.log(` 已有代码 ${chalk.bold('/sillyspec:scan')}`);
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/ docs/<project>/brainstorm/
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');