sillyspec 3.26.10 → 3.26.11

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 (97) hide show
  1. package/.claude/skills/sillyspec-archive/SKILL.md +85 -85
  2. package/.claude/skills/sillyspec-brainstorm/SKILL.md +114 -114
  3. package/.claude/skills/sillyspec-commit/SKILL.md +109 -109
  4. package/.claude/skills/sillyspec-continue/SKILL.md +45 -45
  5. package/.claude/skills/sillyspec-doctor/SKILL.md +76 -76
  6. package/.claude/skills/sillyspec-execute/SKILL.md +200 -200
  7. package/.claude/skills/sillyspec-explore/SKILL.md +95 -95
  8. package/.claude/skills/sillyspec-knowledge/SKILL.md +269 -269
  9. package/.claude/skills/sillyspec-plan/SKILL.md +148 -148
  10. package/.claude/skills/sillyspec-quick/SKILL.md +111 -111
  11. package/.claude/skills/sillyspec-resume/SKILL.md +68 -68
  12. package/.claude/skills/sillyspec-scan/SKILL.md +79 -79
  13. package/.claude/skills/sillyspec-state/SKILL.md +64 -64
  14. package/.claude/skills/sillyspec-status/SKILL.md +54 -54
  15. package/.claude/skills/sillyspec-verify/SKILL.md +83 -83
  16. package/.claude/skills/sillyspec-workspace/SKILL.md +169 -169
  17. package/.gitattributes +2 -0
  18. package/.husky/pre-push +20 -20
  19. package/.npmrc-publish +2 -0
  20. package/README.md +201 -201
  21. package/SKILL.md +90 -90
  22. package/package.json +39 -39
  23. package/packages/dashboard/dist/assets/index-Bq_Z2hne.js +7446 -7446
  24. package/packages/dashboard/dist/assets/index-O2W5RV4z.css +1 -1
  25. package/packages/dashboard/dist/index.html +16 -16
  26. package/packages/dashboard/package.json +25 -25
  27. package/packages/dashboard/server/executor.js +86 -86
  28. package/packages/dashboard/server/index.js +601 -601
  29. package/packages/dashboard/server/parser.js +526 -526
  30. package/src/change-risk-profile.js +254 -254
  31. package/src/classify-change.js +109 -109
  32. package/src/config-schema.js +310 -310
  33. package/src/contract-matrix.js +379 -379
  34. package/src/db.js +350 -350
  35. package/src/dispatch/backends/local-agent.js +155 -155
  36. package/src/dispatch/backends/sillyhub-mcp.js +245 -245
  37. package/src/dispatch/probe.js +210 -210
  38. package/src/dispatch/strategy.js +121 -121
  39. package/src/docs-check.js +131 -4
  40. package/src/doctor-diagnostics.js +711 -711
  41. package/src/endpoint-extractor.js +401 -401
  42. package/src/fs-atomic.js +69 -69
  43. package/src/git-helper.js +79 -79
  44. package/src/hooks/claude-pre-tool-use.cjs +125 -125
  45. package/src/hooks/worktree-guard.js +848 -848
  46. package/src/index.js +90 -8
  47. package/src/init.js +623 -623
  48. package/src/knowledge-match.js +130 -130
  49. package/src/local-detect.js +120 -120
  50. package/src/machine-interface.js +543 -543
  51. package/src/migrate.js +127 -127
  52. package/src/progress/change-registry.js +297 -260
  53. package/src/progress/consistency-doctor.js +355 -355
  54. package/src/progress/shared.js +36 -36
  55. package/src/progress/stage-machine.js +29 -1
  56. package/src/progress/step-store.js +261 -261
  57. package/src/progress.js +1131 -1127
  58. package/src/quicklog.js +693 -693
  59. package/src/review-tier.js +77 -77
  60. package/src/run/command.js +1385 -1364
  61. package/src/run/complete-handlers.js +1443 -1399
  62. package/src/run/complete.js +225 -24
  63. package/src/run/gates.js +755 -755
  64. package/src/run/prompt.js +761 -761
  65. package/src/run/quick-audit.js +155 -146
  66. package/src/run/shared.js +1268 -1215
  67. package/src/run/stage.js +487 -479
  68. package/src/scan-postcheck.js +371 -371
  69. package/src/setup.js +416 -416
  70. package/src/sillyhub-mcp/client.js +529 -529
  71. package/src/spec-sync.js +323 -319
  72. package/src/stage-contract.js +897 -897
  73. package/src/stage-review.js +549 -549
  74. package/src/stages/archive.js +155 -155
  75. package/src/stages/brainstorm-auto.js +236 -236
  76. package/src/stages/brainstorm.js +596 -597
  77. package/src/stages/cmd-existence.js +145 -145
  78. package/src/stages/doctor.js +371 -371
  79. package/src/stages/execute.js +1003 -1003
  80. package/src/stages/explore.js +34 -34
  81. package/src/stages/index.js +29 -29
  82. package/src/stages/knowledge.js +498 -498
  83. package/src/stages/plan-postcheck.js +1302 -1302
  84. package/src/stages/plan.js +625 -623
  85. package/src/stages/quick.js +151 -151
  86. package/src/stages/scan.js +607 -607
  87. package/src/stages/status.js +64 -64
  88. package/src/stages/verify.js +264 -264
  89. package/src/sync.js +1223 -1135
  90. package/src/task-review.js +1019 -1019
  91. package/src/verify-postcheck.js +1186 -1186
  92. package/src/workflow.js +600 -600
  93. package/src/worktree-apply.js +1213 -1136
  94. package/src/worktree-deps.js +353 -353
  95. package/src/worktree.js +1481 -1481
  96. package/templates/workflows/archive-impact.yaml +79 -79
  97. package/templates/workflows/scan-docs.yaml +132 -132
package/src/migrate.js CHANGED
@@ -1,127 +1,127 @@
1
- import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, renameSync, copyFileSync, statSync, cpSync } from 'fs';
2
- import { basename, join, resolve } from 'path';
3
- import chalk from 'chalk';
4
-
5
- /**
6
- * Migrate old .sillyspec/ structure to unified .sillyspec/docs/<project>/ structure
7
- * @param {string} projectDir - Path to the project directory
8
- */
9
- export function migrateDocs(projectDir) {
10
- const sillyspecDir = join(projectDir, '.sillyspec');
11
- if (!existsSync(sillyspecDir)) {
12
- console.error('❌ .sillyspec/ 目录不存在');
13
- process.exit(1);
14
- }
15
-
16
- // Determine project name from projects/*.yaml or directory name
17
- let projectName = basename(resolve(projectDir));
18
- const projectsDir = join(sillyspecDir, 'projects');
19
- if (existsSync(projectsDir)) {
20
- const yamlFiles = readdirSync(projectsDir).filter(f => f.endsWith('.yaml'));
21
- if (yamlFiles.length > 0) {
22
- projectName = yamlFiles[0].replace('.yaml', '');
23
- }
24
- }
25
-
26
- console.log(chalk.cyan(`📦 迁移项目: ${projectName}`));
27
- console.log('');
28
-
29
- const docsBase = join(sillyspecDir, 'docs', projectName);
30
- let migrated = 0;
31
-
32
- // 1. codebase/ → .sillyspec/docs/<project>/scan/
33
- const codebaseDir = join(sillyspecDir, 'codebase');
34
- if (existsSync(codebaseDir)) {
35
- const targetDir = join(docsBase, 'scan');
36
- mkdirSync(targetDir, { recursive: true });
37
- const files = readdirSync(codebaseDir).filter(f => f.endsWith('.md'));
38
- for (const file of files) {
39
- const src = join(codebaseDir, file);
40
- const dest = join(targetDir, file);
41
- if (!existsSync(dest)) {
42
- copyFileSync(src, dest);
43
- console.log(chalk.green(' ✅') + ` scan/${file}`);
44
- migrated++;
45
- } else {
46
- console.log(chalk.yellow(' ⏭️') + ` scan/${file} (已存在)`);
47
- }
48
- }
49
- }
50
-
51
- // 2. specs/ is deprecated — designs live in changes/<变更名>/design.md
52
-
53
- // 3. changes/archive/ → .sillyspec/docs/<project>/archive/
54
- const archiveDir = join(sillyspecDir, 'changes', 'archive');
55
- if (existsSync(archiveDir)) {
56
- const targetDir = join(docsBase, 'archive');
57
- mkdirSync(targetDir, { recursive: true });
58
- const entries = readdirSync(archiveDir);
59
- for (const entry of entries) {
60
- const src = join(archiveDir, entry);
61
- const dest = join(targetDir, entry);
62
- if (!existsSync(dest)) {
63
- // 归档变更本身是目录(含 design.md 等),copyFileSync 对目录源抛 EISDIR;
64
- // 按类型分发:目录用 cpSync 递归、文件用 copyFileSync,单条失败 try/catch 不中断整体迁移
65
- try {
66
- if (statSync(src).isDirectory()) {
67
- cpSync(src, dest, { recursive: true });
68
- } else {
69
- copyFileSync(src, dest);
70
- }
71
- console.log(chalk.green(' ✅') + ` archive/${entry}`);
72
- migrated++;
73
- } catch (err) {
74
- console.log(chalk.yellow(' ⚠️') + ` archive/${entry} 迁移失败: ${err.message}`);
75
- }
76
- } else {
77
- console.log(chalk.yellow(' ⏭️') + ` archive/${entry} (已存在)`);
78
- }
79
- }
80
- }
81
-
82
- // 4. knowledge/ → .sillyspec/docs/<project>/archive/ (append knowledge files)
83
- const knowledgeDir = join(sillyspecDir, 'knowledge');
84
- if (existsSync(knowledgeDir)) {
85
- const targetDir = join(docsBase, 'archive');
86
- mkdirSync(targetDir, { recursive: true });
87
- const files = readdirSync(knowledgeDir).filter(f => f.endsWith('.md'));
88
- for (const file of files) {
89
- const src = join(knowledgeDir, file);
90
- const dest = join(targetDir, `knowledge-${file}`);
91
- if (!existsSync(dest)) {
92
- copyFileSync(src, dest);
93
- console.log(chalk.green(' ✅') + ` archive/knowledge-${file}`);
94
- migrated++;
95
- } else {
96
- console.log(chalk.yellow(' ⏭️') + ` archive/knowledge-${file} (已存在)`);
97
- }
98
- }
99
- }
100
-
101
- // 5. quicklog/ → .sillyspec/docs/<project>/quicklog/
102
- const quicklogDir = join(sillyspecDir, 'quicklog');
103
- if (existsSync(quicklogDir)) {
104
- const targetDir = join(docsBase, 'quicklog');
105
- mkdirSync(targetDir, { recursive: true });
106
- const files = readdirSync(quicklogDir).filter(f => f.endsWith('.md'));
107
- for (const file of files) {
108
- const src = join(quicklogDir, file);
109
- const dest = join(targetDir, file);
110
- if (!existsSync(dest)) {
111
- copyFileSync(src, dest);
112
- console.log(chalk.green(' ✅') + ` quicklog/${file}`);
113
- migrated++;
114
- } else {
115
- console.log(chalk.yellow(' ⏭️') + ` quicklog/${file} (已存在)`);
116
- }
117
- }
118
- }
119
-
120
- console.log('');
121
- if (migrated > 0) {
122
- console.log(chalk.green(` ✅ 迁移完成,共迁移 ${migrated} 个文件`));
123
- console.log(chalk.dim(' 旧文件保留在原位,确认无误后可手动删除'));
124
- } else {
125
- console.log(chalk.yellow(' 没有需要迁移的文件'));
126
- }
127
- }
1
+ import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, renameSync, copyFileSync, statSync, cpSync } from 'fs';
2
+ import { basename, join, resolve } from 'path';
3
+ import chalk from 'chalk';
4
+
5
+ /**
6
+ * Migrate old .sillyspec/ structure to unified .sillyspec/docs/<project>/ structure
7
+ * @param {string} projectDir - Path to the project directory
8
+ */
9
+ export function migrateDocs(projectDir) {
10
+ const sillyspecDir = join(projectDir, '.sillyspec');
11
+ if (!existsSync(sillyspecDir)) {
12
+ console.error('❌ .sillyspec/ 目录不存在');
13
+ process.exit(1);
14
+ }
15
+
16
+ // Determine project name from projects/*.yaml or directory name
17
+ let projectName = basename(resolve(projectDir));
18
+ const projectsDir = join(sillyspecDir, 'projects');
19
+ if (existsSync(projectsDir)) {
20
+ const yamlFiles = readdirSync(projectsDir).filter(f => f.endsWith('.yaml'));
21
+ if (yamlFiles.length > 0) {
22
+ projectName = yamlFiles[0].replace('.yaml', '');
23
+ }
24
+ }
25
+
26
+ console.log(chalk.cyan(`📦 迁移项目: ${projectName}`));
27
+ console.log('');
28
+
29
+ const docsBase = join(sillyspecDir, 'docs', projectName);
30
+ let migrated = 0;
31
+
32
+ // 1. codebase/ → .sillyspec/docs/<project>/scan/
33
+ const codebaseDir = join(sillyspecDir, 'codebase');
34
+ if (existsSync(codebaseDir)) {
35
+ const targetDir = join(docsBase, 'scan');
36
+ mkdirSync(targetDir, { recursive: true });
37
+ const files = readdirSync(codebaseDir).filter(f => f.endsWith('.md'));
38
+ for (const file of files) {
39
+ const src = join(codebaseDir, file);
40
+ const dest = join(targetDir, file);
41
+ if (!existsSync(dest)) {
42
+ copyFileSync(src, dest);
43
+ console.log(chalk.green(' ✅') + ` scan/${file}`);
44
+ migrated++;
45
+ } else {
46
+ console.log(chalk.yellow(' ⏭️') + ` scan/${file} (已存在)`);
47
+ }
48
+ }
49
+ }
50
+
51
+ // 2. specs/ is deprecated — designs live in changes/<变更名>/design.md
52
+
53
+ // 3. changes/archive/ → .sillyspec/docs/<project>/archive/
54
+ const archiveDir = join(sillyspecDir, 'changes', 'archive');
55
+ if (existsSync(archiveDir)) {
56
+ const targetDir = join(docsBase, 'archive');
57
+ mkdirSync(targetDir, { recursive: true });
58
+ const entries = readdirSync(archiveDir);
59
+ for (const entry of entries) {
60
+ const src = join(archiveDir, entry);
61
+ const dest = join(targetDir, entry);
62
+ if (!existsSync(dest)) {
63
+ // 归档变更本身是目录(含 design.md 等),copyFileSync 对目录源抛 EISDIR;
64
+ // 按类型分发:目录用 cpSync 递归、文件用 copyFileSync,单条失败 try/catch 不中断整体迁移
65
+ try {
66
+ if (statSync(src).isDirectory()) {
67
+ cpSync(src, dest, { recursive: true });
68
+ } else {
69
+ copyFileSync(src, dest);
70
+ }
71
+ console.log(chalk.green(' ✅') + ` archive/${entry}`);
72
+ migrated++;
73
+ } catch (err) {
74
+ console.log(chalk.yellow(' ⚠️') + ` archive/${entry} 迁移失败: ${err.message}`);
75
+ }
76
+ } else {
77
+ console.log(chalk.yellow(' ⏭️') + ` archive/${entry} (已存在)`);
78
+ }
79
+ }
80
+ }
81
+
82
+ // 4. knowledge/ → .sillyspec/docs/<project>/archive/ (append knowledge files)
83
+ const knowledgeDir = join(sillyspecDir, 'knowledge');
84
+ if (existsSync(knowledgeDir)) {
85
+ const targetDir = join(docsBase, 'archive');
86
+ mkdirSync(targetDir, { recursive: true });
87
+ const files = readdirSync(knowledgeDir).filter(f => f.endsWith('.md'));
88
+ for (const file of files) {
89
+ const src = join(knowledgeDir, file);
90
+ const dest = join(targetDir, `knowledge-${file}`);
91
+ if (!existsSync(dest)) {
92
+ copyFileSync(src, dest);
93
+ console.log(chalk.green(' ✅') + ` archive/knowledge-${file}`);
94
+ migrated++;
95
+ } else {
96
+ console.log(chalk.yellow(' ⏭️') + ` archive/knowledge-${file} (已存在)`);
97
+ }
98
+ }
99
+ }
100
+
101
+ // 5. quicklog/ → .sillyspec/docs/<project>/quicklog/
102
+ const quicklogDir = join(sillyspecDir, 'quicklog');
103
+ if (existsSync(quicklogDir)) {
104
+ const targetDir = join(docsBase, 'quicklog');
105
+ mkdirSync(targetDir, { recursive: true });
106
+ const files = readdirSync(quicklogDir).filter(f => f.endsWith('.md'));
107
+ for (const file of files) {
108
+ const src = join(quicklogDir, file);
109
+ const dest = join(targetDir, file);
110
+ if (!existsSync(dest)) {
111
+ copyFileSync(src, dest);
112
+ console.log(chalk.green(' ✅') + ` quicklog/${file}`);
113
+ migrated++;
114
+ } else {
115
+ console.log(chalk.yellow(' ⏭️') + ` quicklog/${file} (已存在)`);
116
+ }
117
+ }
118
+ }
119
+
120
+ console.log('');
121
+ if (migrated > 0) {
122
+ console.log(chalk.green(` ✅ 迁移完成,共迁移 ${migrated} 个文件`));
123
+ console.log(chalk.dim(' 旧文件保留在原位,确认无误后可手动删除'));
124
+ } else {
125
+ console.log(chalk.yellow(' 没有需要迁移的文件'));
126
+ }
127
+ }