sillyspec 3.26.9 → 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 (98) 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 -81
  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 -675
  59. package/src/review-tier.js +77 -77
  60. package/src/run/command.js +1385 -1364
  61. package/src/run/complete-handlers.js +198 -9
  62. package/src/run/complete.js +225 -24
  63. package/src/run/concurrent-detect.js +22 -0
  64. package/src/run/gates.js +755 -755
  65. package/src/run/prompt.js +761 -721
  66. package/src/run/quick-audit.js +155 -146
  67. package/src/run/shared.js +1268 -1197
  68. package/src/run/stage.js +487 -479
  69. package/src/scan-postcheck.js +371 -371
  70. package/src/setup.js +416 -416
  71. package/src/sillyhub-mcp/client.js +529 -529
  72. package/src/spec-sync.js +323 -0
  73. package/src/stage-contract.js +897 -897
  74. package/src/stage-review.js +549 -549
  75. package/src/stages/archive.js +155 -154
  76. package/src/stages/brainstorm-auto.js +236 -236
  77. package/src/stages/brainstorm.js +596 -597
  78. package/src/stages/cmd-existence.js +145 -145
  79. package/src/stages/doctor.js +371 -371
  80. package/src/stages/execute.js +1003 -991
  81. package/src/stages/explore.js +34 -34
  82. package/src/stages/index.js +29 -29
  83. package/src/stages/knowledge.js +498 -498
  84. package/src/stages/plan-postcheck.js +1302 -1281
  85. package/src/stages/plan.js +625 -604
  86. package/src/stages/quick.js +151 -143
  87. package/src/stages/scan.js +606 -605
  88. package/src/stages/status.js +64 -64
  89. package/src/stages/verify.js +264 -261
  90. package/src/sync.js +1223 -1125
  91. package/src/task-review.js +1019 -1019
  92. package/src/verify-postcheck.js +1186 -1186
  93. package/src/workflow.js +600 -600
  94. package/src/worktree-apply.js +1213 -1136
  95. package/src/worktree-deps.js +353 -353
  96. package/src/worktree.js +1481 -1437
  97. package/templates/workflows/archive-impact.yaml +79 -79
  98. package/templates/workflows/scan-docs.yaml +132 -132
@@ -1,109 +1,109 @@
1
- /**
2
- * classify-change.js — 变更规模分类器
3
- *
4
- * 将用户需求描述分类为 quick / auto / full,
5
- * 供 auto 模式决定内部流程深度。
6
- */
7
-
8
- import { existsSync, readFileSync } from 'fs'
9
- import { join } from 'path'
10
- import jsYaml from 'js-yaml'
11
-
12
- /**
13
- * 用户显式指定的关键词 → 强制模式
14
- */
15
- const FORCE_FULL_PATTERNS = [
16
- /数据库|database|schema/i,
17
- /迁移|migration|migrate/i,
18
- /鉴权|权限|auth|permission|rbac/i,
19
- /支付|payment|billing/i,
20
- /重构|refactor.*architectur/i,
21
- /微服务|microserv/i,
22
- ]
23
-
24
- const FORCE_QUICK_PATTERNS = [
25
- /fix typo/i,
26
- /更新文案|改文案|文案修改/i,
27
- /样式调整|style.*tweak/i,
28
- /修复.*\s*\bbug\b.*\bfix\b/i,
29
- ]
30
-
31
- /**
32
- * 读 local.yaml 的 auto_mode 段(best-effort,绝不抛)。
33
- * 供 runCommand 接线:传给 classifyChange 的 localConfig,让 force_*_patterns 真生效。
34
- * @param {string} cwd - 主仓库根(local.yaml 在 <cwd>/.sillyspec/local.yaml)
35
- * @returns {{ force_full_patterns?: string[], force_quick_patterns?: string[] } | null}
36
- * auto_mode 段含至少一个 string pattern → 归一化数组;文件缺/解析失败/无段/空 → null(降级默认关键词)
37
- */
38
- export function readAutoModeFromLocalYaml(cwd) {
39
- try {
40
- const p = join(cwd, '.sillyspec', 'local.yaml')
41
- if (!existsSync(p)) return null
42
- const doc = jsYaml.load(readFileSync(p, 'utf8'))
43
- if (!doc || typeof doc !== 'object') return null
44
- const am = doc.auto_mode
45
- if (!am || typeof am !== 'object') return null
46
- const ffp = Array.isArray(am.force_full_patterns) ? am.force_full_patterns.filter(s => typeof s === 'string') : []
47
- const fqp = Array.isArray(am.force_quick_patterns) ? am.force_quick_patterns.filter(s => typeof s === 'string') : []
48
- if (ffp.length === 0 && fqp.length === 0) return null
49
- return { force_full_patterns: ffp, force_quick_patterns: fqp }
50
- } catch {
51
- return null
52
- }
53
- }
54
-
55
- /**
56
- * 分类变更规模
57
- * @param {object} opts
58
- * @param {string} opts.description - 用户需求描述
59
- * @param {string} [opts.explicitMode] - 用户显式指定的模式(auto/quick/full)
60
- * @param {object} [opts.localConfig] - local.yaml auto_mode 段(由 readAutoModeFromLocalYaml 读出)
61
- * @returns {{ mode: 'quick'|'auto'|'full', reason: string }}
62
- */
63
- export function classifyChange({ description = '', explicitMode, localConfig } = {}) {
64
- // 1. 用户显式指定优先级最高
65
- if (explicitMode && ['quick', 'auto', 'full'].includes(explicitMode)) {
66
- return { mode: explicitMode, reason: '用户显式指定' }
67
- }
68
-
69
- // 2. local.yaml force patterns
70
- if (localConfig) {
71
- const forceFullPatterns = localConfig.force_full_patterns || []
72
- const forceQuickPatterns = localConfig.force_quick_patterns || []
73
-
74
- for (const pattern of forceFullPatterns) {
75
- try {
76
- if (new RegExp(pattern, 'i').test(description)) {
77
- return { mode: 'full', reason: `local.yaml force_full_pattern 匹配: ${pattern}` }
78
- }
79
- } catch {
80
- // 非法正则跳过,不崩 auto 分类(review-2026-08-09 #30)
81
- }
82
- }
83
- for (const pattern of forceQuickPatterns) {
84
- try {
85
- if (new RegExp(pattern, 'i').test(description)) {
86
- return { mode: 'quick', reason: `local.yaml force_quick_pattern 匹配: ${pattern}` }
87
- }
88
- } catch {
89
- // 非法正则跳过
90
- }
91
- }
92
- }
93
-
94
- // 3. 默认关键词匹配
95
- for (const pattern of FORCE_QUICK_PATTERNS) {
96
- if (pattern.test(description)) {
97
- return { mode: 'quick', reason: `命中 quick 关键词: ${pattern.source}` }
98
- }
99
- }
100
-
101
- for (const pattern of FORCE_FULL_PATTERNS) {
102
- if (pattern.test(description)) {
103
- return { mode: 'full', reason: `命中 full 关键词: ${pattern.source}` }
104
- }
105
- }
106
-
107
- // 4. 默认 auto
108
- return { mode: 'auto', reason: '默认模式' }
109
- }
1
+ /**
2
+ * classify-change.js — 变更规模分类器
3
+ *
4
+ * 将用户需求描述分类为 quick / auto / full,
5
+ * 供 auto 模式决定内部流程深度。
6
+ */
7
+
8
+ import { existsSync, readFileSync } from 'fs'
9
+ import { join } from 'path'
10
+ import jsYaml from 'js-yaml'
11
+
12
+ /**
13
+ * 用户显式指定的关键词 → 强制模式
14
+ */
15
+ const FORCE_FULL_PATTERNS = [
16
+ /数据库|database|schema/i,
17
+ /迁移|migration|migrate/i,
18
+ /鉴权|权限|auth|permission|rbac/i,
19
+ /支付|payment|billing/i,
20
+ /重构|refactor.*architectur/i,
21
+ /微服务|microserv/i,
22
+ ]
23
+
24
+ const FORCE_QUICK_PATTERNS = [
25
+ /fix typo/i,
26
+ /更新文案|改文案|文案修改/i,
27
+ /样式调整|style.*tweak/i,
28
+ /修复.*\s*\bbug\b.*\bfix\b/i,
29
+ ]
30
+
31
+ /**
32
+ * 读 local.yaml 的 auto_mode 段(best-effort,绝不抛)。
33
+ * 供 runCommand 接线:传给 classifyChange 的 localConfig,让 force_*_patterns 真生效。
34
+ * @param {string} cwd - 主仓库根(local.yaml 在 <cwd>/.sillyspec/local.yaml)
35
+ * @returns {{ force_full_patterns?: string[], force_quick_patterns?: string[] } | null}
36
+ * auto_mode 段含至少一个 string pattern → 归一化数组;文件缺/解析失败/无段/空 → null(降级默认关键词)
37
+ */
38
+ export function readAutoModeFromLocalYaml(cwd) {
39
+ try {
40
+ const p = join(cwd, '.sillyspec', 'local.yaml')
41
+ if (!existsSync(p)) return null
42
+ const doc = jsYaml.load(readFileSync(p, 'utf8'))
43
+ if (!doc || typeof doc !== 'object') return null
44
+ const am = doc.auto_mode
45
+ if (!am || typeof am !== 'object') return null
46
+ const ffp = Array.isArray(am.force_full_patterns) ? am.force_full_patterns.filter(s => typeof s === 'string') : []
47
+ const fqp = Array.isArray(am.force_quick_patterns) ? am.force_quick_patterns.filter(s => typeof s === 'string') : []
48
+ if (ffp.length === 0 && fqp.length === 0) return null
49
+ return { force_full_patterns: ffp, force_quick_patterns: fqp }
50
+ } catch {
51
+ return null
52
+ }
53
+ }
54
+
55
+ /**
56
+ * 分类变更规模
57
+ * @param {object} opts
58
+ * @param {string} opts.description - 用户需求描述
59
+ * @param {string} [opts.explicitMode] - 用户显式指定的模式(auto/quick/full)
60
+ * @param {object} [opts.localConfig] - local.yaml auto_mode 段(由 readAutoModeFromLocalYaml 读出)
61
+ * @returns {{ mode: 'quick'|'auto'|'full', reason: string }}
62
+ */
63
+ export function classifyChange({ description = '', explicitMode, localConfig } = {}) {
64
+ // 1. 用户显式指定优先级最高
65
+ if (explicitMode && ['quick', 'auto', 'full'].includes(explicitMode)) {
66
+ return { mode: explicitMode, reason: '用户显式指定' }
67
+ }
68
+
69
+ // 2. local.yaml force patterns
70
+ if (localConfig) {
71
+ const forceFullPatterns = localConfig.force_full_patterns || []
72
+ const forceQuickPatterns = localConfig.force_quick_patterns || []
73
+
74
+ for (const pattern of forceFullPatterns) {
75
+ try {
76
+ if (new RegExp(pattern, 'i').test(description)) {
77
+ return { mode: 'full', reason: `local.yaml force_full_pattern 匹配: ${pattern}` }
78
+ }
79
+ } catch {
80
+ // 非法正则跳过,不崩 auto 分类(review-2026-08-09 #30)
81
+ }
82
+ }
83
+ for (const pattern of forceQuickPatterns) {
84
+ try {
85
+ if (new RegExp(pattern, 'i').test(description)) {
86
+ return { mode: 'quick', reason: `local.yaml force_quick_pattern 匹配: ${pattern}` }
87
+ }
88
+ } catch {
89
+ // 非法正则跳过
90
+ }
91
+ }
92
+ }
93
+
94
+ // 3. 默认关键词匹配
95
+ for (const pattern of FORCE_QUICK_PATTERNS) {
96
+ if (pattern.test(description)) {
97
+ return { mode: 'quick', reason: `命中 quick 关键词: ${pattern.source}` }
98
+ }
99
+ }
100
+
101
+ for (const pattern of FORCE_FULL_PATTERNS) {
102
+ if (pattern.test(description)) {
103
+ return { mode: 'full', reason: `命中 full 关键词: ${pattern.source}` }
104
+ }
105
+ }
106
+
107
+ // 4. 默认 auto
108
+ return { mode: 'auto', reason: '默认模式' }
109
+ }