sillyspec 3.9.0 → 3.10.0
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 +17 -0
- package/.claude/skills/sillyspec-auto/SKILL.md +78 -0
- package/.claude/skills/sillyspec-brainstorm/SKILL.md +17 -0
- package/{templates/commit.md → .claude/skills/sillyspec-commit/SKILL.md} +32 -47
- package/.claude/skills/sillyspec-continue/SKILL.md +45 -0
- package/.claude/skills/sillyspec-doctor/SKILL.md +27 -0
- package/.claude/skills/sillyspec-execute/SKILL.md +17 -0
- package/.claude/skills/sillyspec-explore/SKILL.md +105 -0
- package/.claude/skills/sillyspec-export/SKILL.md +53 -0
- package/.claude/skills/sillyspec-init/SKILL.md +170 -0
- package/.claude/skills/sillyspec-plan/SKILL.md +17 -0
- package/.claude/skills/sillyspec-propose/SKILL.md +17 -0
- package/.claude/skills/sillyspec-quick/SKILL.md +17 -0
- package/.claude/skills/sillyspec-resume/SKILL.md +111 -0
- package/.claude/skills/sillyspec-scan/SKILL.md +17 -0
- package/.claude/skills/sillyspec-state/SKILL.md +54 -0
- package/.claude/skills/sillyspec-status/SKILL.md +17 -0
- package/.claude/skills/sillyspec-verify/SKILL.md +17 -0
- package/.claude/skills/sillyspec-workspace/SKILL.md +149 -0
- package/README.md +19 -11
- package/SKILL.md +15 -10
- package/package.json +7 -9
- package/packages/dashboard/dist/assets/index-BcM2J-hv.css +1 -0
- package/packages/dashboard/dist/assets/index-DpLHK4jv.js +7446 -0
- package/packages/dashboard/dist/index.html +16 -16
- package/packages/dashboard/dist/prototype-dashboard.html +836 -0
- package/packages/dashboard/dist/prototype-overview.html +256 -0
- package/packages/dashboard/package-lock.json +226 -6
- package/packages/dashboard/package.json +8 -5
- package/packages/dashboard/public/logo.jpg +0 -0
- package/packages/dashboard/public/prototype-dashboard.html +836 -0
- package/packages/dashboard/public/prototype-overview.html +256 -0
- package/packages/dashboard/server/executor.js +1 -1
- package/packages/dashboard/server/index.js +341 -113
- package/packages/dashboard/server/parser.js +442 -30
- package/packages/dashboard/server/watcher.js +214 -134
- package/packages/dashboard/src/App.vue +475 -71
- package/packages/dashboard/src/components/ActionBar.vue +36 -43
- package/packages/dashboard/src/components/CommandPalette.vue +45 -66
- package/packages/dashboard/src/components/DetailPanel.vue +68 -53
- package/packages/dashboard/src/components/DocPreview.vue +257 -0
- package/packages/dashboard/src/components/DocTree.vue +114 -0
- package/packages/dashboard/src/components/HResizeHandle.vue +48 -0
- package/packages/dashboard/src/components/LogStream.vue +13 -33
- package/packages/dashboard/src/components/PipelineStage.vue +8 -8
- package/packages/dashboard/src/components/PipelineView.vue +99 -45
- package/packages/dashboard/src/components/ProjectCard.vue +187 -0
- package/packages/dashboard/src/components/ProjectList.vue +103 -45
- package/packages/dashboard/src/components/ProjectOverview.vue +152 -0
- package/packages/dashboard/src/components/StageBadge.vue +13 -13
- package/packages/dashboard/src/components/StepCard.vue +15 -15
- package/packages/dashboard/src/components/VResizeHandle.vue +61 -0
- 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/composables/useDashboard.js +48 -6
- package/packages/dashboard/src/composables/useKeyboard.js +6 -4
- package/packages/dashboard/src/composables/useLayout.js +131 -0
- package/packages/dashboard/src/main.js +4 -1
- package/packages/dashboard/src/style.css +17 -17
- package/src/index.js +141 -22
- package/src/init.js +93 -231
- package/src/migrate.js +117 -0
- package/src/progress.js +460 -0
- package/src/run.js +635 -0
- package/src/setup.js +2 -72
- package/src/stages/archive.js +54 -0
- package/src/stages/brainstorm.js +264 -0
- package/src/stages/doctor.js +303 -0
- package/src/stages/execute.js +287 -0
- package/src/stages/explore.js +34 -0
- package/src/stages/index.js +28 -0
- package/src/stages/plan.js +354 -0
- package/src/stages/propose.js +115 -0
- package/src/stages/quick.js +64 -0
- package/src/stages/scan.js +141 -0
- package/src/stages/status.js +65 -0
- package/src/stages/verify.js +135 -0
- package/.sillyspec/changes/dashboard/design.md +0 -219
- package/.sillyspec/plans/2026-04-05-dashboard.md +0 -737
- package/.sillyspec/specs/2026-04-05-dashboard-design.md +0 -206
- package/dist/steps/brainstorm/01-load-context.md +0 -30
- package/dist/steps/brainstorm/02-reuse-check.md +0 -6
- package/dist/steps/brainstorm/03-prototype-analysis.md +0 -11
- package/dist/steps/brainstorm/04-module-split.md +0 -23
- package/dist/steps/brainstorm/05-dialog-explore.md +0 -8
- package/dist/steps/brainstorm/06-propose-approaches.md +0 -3
- package/dist/steps/brainstorm/07-present-design.md +0 -3
- package/dist/steps/brainstorm/08-write-design.md +0 -21
- package/dist/steps/brainstorm/09-self-review.md +0 -15
- package/dist/steps/brainstorm/10-user-confirm.md +0 -3
- package/dist/steps/brainstorm/11-output-spec.md +0 -7
- package/dist/steps/brainstorm/manifest.yaml +0 -26
- package/dist/steps/execute/01-load-context.md +0 -41
- package/dist/steps/execute/02-scan-conventions.md +0 -47
- package/dist/steps/execute/03-skill-mcp.md +0 -19
- package/dist/steps/execute/04-assign-task.md +0 -22
- package/dist/steps/execute/04b-prompt-template.md +0 -54
- package/dist/steps/execute/05-write-test.md +0 -7
- package/dist/steps/execute/06-write-code.md +0 -8
- package/dist/steps/execute/07-run-test.md +0 -26
- package/dist/steps/execute/08-fix-issues.md +0 -28
- package/dist/steps/execute/09-next-task.md +0 -33
- package/dist/steps/execute/manifest.yaml +0 -28
- package/dist/steps/plan/01-load-context.md +0 -22
- package/dist/steps/plan/02-anchor-confirm.md +0 -1
- package/dist/steps/plan/03-expand-tasks.md +0 -33
- package/dist/steps/plan/04-mark-order.md +0 -15
- package/dist/steps/plan/05-e2e-planning.md +0 -17
- package/dist/steps/plan/06-self-check.md +0 -16
- package/dist/steps/plan/07-save.md +0 -1
- package/dist/steps/plan/manifest.yaml +0 -18
- package/dist/steps/scan/01-env-detect.md +0 -51
- package/dist/steps/scan/02-tech-stack.md +0 -16
- package/dist/steps/scan/03-conventions.md +0 -16
- package/dist/steps/scan/04-structure.md +0 -19
- package/dist/steps/scan/05-quality.md +0 -18
- package/dist/steps/scan/06-complete.md +0 -49
- package/dist/steps/scan/manifest.yaml +0 -16
- package/dist/steps/verify/01-load-specs.md +0 -28
- package/dist/steps/verify/02-check-tasks.md +0 -1
- package/dist/steps/verify/03-check-design.md +0 -6
- package/dist/steps/verify/04-run-tests.md +0 -7
- package/dist/steps/verify/05-e2e-tests.md +0 -27
- package/dist/steps/verify/05b-e2e-fix.md +0 -33
- package/dist/steps/verify/06-code-quality.md +0 -25
- package/dist/steps/verify/07-lint-check.md +0 -27
- package/dist/steps/verify/08-output-report.md +0 -14
- package/dist/steps/verify/manifest.yaml +0 -22
- package/docs/.vitepress/config.mts +0 -45
- package/docs/.vitepress/dist/404.html +0 -25
- package/docs/.vitepress/dist/assets/app.YytxICdd.js +0 -1
- package/docs/.vitepress/dist/assets/chunks/framework.Czhw_PXq.js +0 -19
- package/docs/.vitepress/dist/assets/chunks/theme.DusTRZQk.js +0 -1
- package/docs/.vitepress/dist/assets/index.md.C3VCvtQA.js +0 -1
- package/docs/.vitepress/dist/assets/index.md.C3VCvtQA.lean.js +0 -1
- package/docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/docs/.vitepress/dist/assets/sillyspec_commands.md.CXFFsj08.js +0 -15
- package/docs/.vitepress/dist/assets/sillyspec_commands.md.CXFFsj08.lean.js +0 -1
- package/docs/.vitepress/dist/assets/sillyspec_dashboard.md.BuPXHqjX.js +0 -4
- package/docs/.vitepress/dist/assets/sillyspec_dashboard.md.BuPXHqjX.lean.js +0 -1
- package/docs/.vitepress/dist/assets/sillyspec_file-io.md.Cz3x7llx.js +0 -1
- package/docs/.vitepress/dist/assets/sillyspec_file-io.md.Cz3x7llx.lean.js +0 -1
- package/docs/.vitepress/dist/assets/sillyspec_getting-started.md.ClcvV8k3.js +0 -4
- package/docs/.vitepress/dist/assets/sillyspec_getting-started.md.ClcvV8k3.lean.js +0 -1
- package/docs/.vitepress/dist/assets/sillyspec_install.md.CKuR2tiT.js +0 -5
- package/docs/.vitepress/dist/assets/sillyspec_install.md.CKuR2tiT.lean.js +0 -1
- package/docs/.vitepress/dist/assets/sillyspec_lifecycle.md.DY293cR1.js +0 -28
- package/docs/.vitepress/dist/assets/sillyspec_lifecycle.md.DY293cR1.lean.js +0 -1
- package/docs/.vitepress/dist/assets/sillyspec_structure.md.sVYS4zPs.js +0 -30
- package/docs/.vitepress/dist/assets/sillyspec_structure.md.sVYS4zPs.lean.js +0 -1
- package/docs/.vitepress/dist/assets/style.DFTx90Kk.css +0 -1
- package/docs/.vitepress/dist/hashmap.json +0 -1
- package/docs/.vitepress/dist/index.html +0 -28
- package/docs/.vitepress/dist/sillyspec/commands.html +0 -42
- package/docs/.vitepress/dist/sillyspec/dashboard.html +0 -31
- package/docs/.vitepress/dist/sillyspec/file-io.html +0 -28
- package/docs/.vitepress/dist/sillyspec/getting-started.html +0 -31
- package/docs/.vitepress/dist/sillyspec/install.html +0 -32
- package/docs/.vitepress/dist/sillyspec/lifecycle.html +0 -55
- package/docs/.vitepress/dist/sillyspec/structure.html +0 -57
- package/docs/.vitepress/dist/vp-icons.css +0 -1
- package/docs/index.md +0 -34
- package/docs/sillyspec/commands.md +0 -218
- package/docs/sillyspec/dashboard.md +0 -51
- package/docs/sillyspec/file-io.md +0 -34
- package/docs/sillyspec/getting-started.md +0 -61
- package/docs/sillyspec/install.md +0 -51
- package/docs/sillyspec/lifecycle.md +0 -146
- package/docs/sillyspec/structure.md +0 -62
- package/packages/dashboard/dist/assets/index-Bh-GPjKY.css +0 -1
- package/packages/dashboard/dist/assets/index-CrCn5Gg6.js +0 -17
- package/src/step.js +0 -543
- package/templates/archive.md +0 -120
- package/templates/brainstorm.md +0 -170
- package/templates/continue.md +0 -32
- package/templates/execute.md +0 -304
- package/templates/explore.md +0 -59
- package/templates/export.md +0 -21
- package/templates/init.md +0 -61
- package/templates/plan.md +0 -146
- package/templates/quick.md +0 -135
- package/templates/scan-quick.md +0 -49
- package/templates/scan.md +0 -156
- package/templates/skills/playwright-e2e/SKILL.md +0 -340
- package/templates/status.md +0 -75
- package/templates/verify.md +0 -236
- package/templates/workspace-sync.md +0 -99
- package/templates/workspace.md +0 -70
- /package/{docs/.vitepress/dist/logo.jpg → logo.jpg} +0 -0
- /package/{docs/.vitepress → packages/dashboard}/dist/favicon.jpg +0 -0
- /package/{docs/public → packages/dashboard/dist}/logo.jpg +0 -0
- /package/{docs → packages/dashboard}/public/favicon.jpg +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 布局管理 Composable
|
|
3
|
+
* 管理双层布局的概览/详情比例和三栏宽度
|
|
4
|
+
*/
|
|
5
|
+
import { reactive, ref, onMounted } from 'vue'
|
|
6
|
+
|
|
7
|
+
const STORAGE_KEY = 'dashboard-layout-v2'
|
|
8
|
+
|
|
9
|
+
// 默认值
|
|
10
|
+
const DEFAULT_OVERVIEW_HEIGHT = 30 // 概览区域百分比
|
|
11
|
+
const DEFAULT_COLUMN_WIDTHS = [33.33, 33.33, 33.33] // 三栏宽度百分比
|
|
12
|
+
|
|
13
|
+
// 最小值限制
|
|
14
|
+
const MIN_OVERVIEW_HEIGHT = 15
|
|
15
|
+
const MAX_OVERVIEW_HEIGHT = 75
|
|
16
|
+
const MIN_COLUMN_WIDTH = 10
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 布局管理 Hook
|
|
20
|
+
*/
|
|
21
|
+
export function useLayout() {
|
|
22
|
+
// 布局状态
|
|
23
|
+
const layout = reactive({
|
|
24
|
+
overviewHeight: DEFAULT_OVERVIEW_HEIGHT,
|
|
25
|
+
columnWidths: [...DEFAULT_COLUMN_WIDTHS]
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
// 拖动状态
|
|
29
|
+
const isDragging = ref(false)
|
|
30
|
+
const dragType = ref(null) // 'vertical' | 'horizontal'
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 加载保存的布局
|
|
34
|
+
*/
|
|
35
|
+
function loadLayout() {
|
|
36
|
+
try {
|
|
37
|
+
const saved = localStorage.getItem(STORAGE_KEY)
|
|
38
|
+
if (saved) {
|
|
39
|
+
const parsed = JSON.parse(saved)
|
|
40
|
+
if (parsed.overviewHeight !== undefined) {
|
|
41
|
+
layout.overviewHeight = Math.max(MIN_OVERVIEW_HEIGHT, Math.min(MAX_OVERVIEW_HEIGHT, parsed.overviewHeight))
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(parsed.columnWidths) && parsed.columnWidths.length === 3) {
|
|
44
|
+
layout.columnWidths = parsed.columnWidths
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
console.error('Failed to load layout:', e)
|
|
49
|
+
// 使用默认值
|
|
50
|
+
resetLayout()
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 保存布局到 localStorage
|
|
56
|
+
*/
|
|
57
|
+
function saveLayout() {
|
|
58
|
+
try {
|
|
59
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify({
|
|
60
|
+
overviewHeight: layout.overviewHeight,
|
|
61
|
+
columnWidths: layout.columnWidths
|
|
62
|
+
}))
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error('Failed to save layout:', e)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 重置布局为默认值
|
|
70
|
+
*/
|
|
71
|
+
function resetLayout() {
|
|
72
|
+
layout.overviewHeight = DEFAULT_OVERVIEW_HEIGHT
|
|
73
|
+
layout.columnWidths = [...DEFAULT_COLUMN_WIDTHS]
|
|
74
|
+
saveLayout()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 设置概览区域高度(百分比)
|
|
79
|
+
*/
|
|
80
|
+
function setOverviewHeight(percent) {
|
|
81
|
+
layout.overviewHeight = Math.max(MIN_OVERVIEW_HEIGHT, Math.min(MAX_OVERVIEW_HEIGHT, percent))
|
|
82
|
+
saveLayout()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 设置列宽度(索引,百分比)
|
|
87
|
+
*/
|
|
88
|
+
function setColumnWidth(index, percent) {
|
|
89
|
+
if (index >= 0 && index < 3) {
|
|
90
|
+
layout.columnWidths[index] = Math.max(MIN_COLUMN_WIDTH, percent)
|
|
91
|
+
saveLayout()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* 开始拖动
|
|
97
|
+
*/
|
|
98
|
+
function startDrag(type) {
|
|
99
|
+
isDragging.value = true
|
|
100
|
+
dragType.value = type
|
|
101
|
+
document.body.classList.add('resizing')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 结束拖动
|
|
106
|
+
*/
|
|
107
|
+
function endDrag() {
|
|
108
|
+
isDragging.value = false
|
|
109
|
+
dragType.value = null
|
|
110
|
+
document.body.classList.remove('resizing')
|
|
111
|
+
saveLayout()
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 组件挂载时加载布局
|
|
115
|
+
onMounted(() => {
|
|
116
|
+
loadLayout()
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
layout,
|
|
121
|
+
isDragging,
|
|
122
|
+
dragType,
|
|
123
|
+
loadLayout,
|
|
124
|
+
saveLayout,
|
|
125
|
+
resetLayout,
|
|
126
|
+
setOverviewHeight,
|
|
127
|
+
setColumnWidth,
|
|
128
|
+
startDrag,
|
|
129
|
+
endDrag
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
@import "tailwindcss";
|
|
2
2
|
|
|
3
3
|
@theme {
|
|
4
|
-
--color-bg: #
|
|
5
|
-
--color-primary: #
|
|
6
|
-
--color-primary-dim: #
|
|
7
|
-
--color-warning: #
|
|
8
|
-
--color-danger: #
|
|
9
|
-
--color-muted: #
|
|
10
|
-
--color-surface: #
|
|
11
|
-
--color-surface-2: #
|
|
12
|
-
--color-border: #
|
|
13
|
-
--color-border-light: #
|
|
14
|
-
--color-text: #
|
|
15
|
-
--color-text-secondary: #
|
|
16
|
-
--color-info: #
|
|
17
|
-
--color-success: #
|
|
4
|
+
--color-bg: #F5F5F7;
|
|
5
|
+
--color-primary: #D97706;
|
|
6
|
+
--color-primary-dim: #92400E;
|
|
7
|
+
--color-warning: #EA580C;
|
|
8
|
+
--color-danger: #DC2626;
|
|
9
|
+
--color-muted: #6B7280;
|
|
10
|
+
--color-surface: #FFFFFF;
|
|
11
|
+
--color-surface-2: #F0F0F3;
|
|
12
|
+
--color-border: #E5E5EA;
|
|
13
|
+
--color-border-light: #D1D1D6;
|
|
14
|
+
--color-text: #1C1C1E;
|
|
15
|
+
--color-text-secondary: #636366;
|
|
16
|
+
--color-info: #2563EB;
|
|
17
|
+
--color-success: #16A34A;
|
|
18
18
|
|
|
19
19
|
--font-display: 'JetBrains Mono', monospace;
|
|
20
20
|
--font-body: 'DM Sans', sans-serif;
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
|
|
97
97
|
/* Skeleton shimmer */
|
|
98
98
|
.skeleton-shimmer {
|
|
99
|
-
background: linear-gradient(90deg, #
|
|
99
|
+
background: linear-gradient(90deg, #1A1E28 25%, #2A3040 50%, #1A1E28 75%);
|
|
100
100
|
background-size: 200% 100%;
|
|
101
101
|
animation: shimmer 1.5s ease-in-out infinite;
|
|
102
102
|
}
|
|
@@ -112,12 +112,12 @@
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
::-webkit-scrollbar-thumb {
|
|
115
|
-
background: #
|
|
115
|
+
background: #2A3040;
|
|
116
116
|
border-radius: 10px;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
::-webkit-scrollbar-thumb:hover {
|
|
120
|
-
background: #
|
|
120
|
+
background: #3A4555;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
* {
|
package/src/index.js
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
* SillySpec CLI — 安装工具
|
|
5
5
|
*
|
|
6
6
|
* 只负责两件事:init(安装命令模板)和 setup(安装 MCP 工具)。
|
|
7
|
-
*
|
|
7
|
+
* 状态管理通过 progress.json 完成,使用 `sillyspec progress` 命令。
|
|
8
8
|
*/
|
|
9
|
-
import { existsSync } from 'fs';
|
|
10
|
-
import { resolve } from 'path';
|
|
9
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
10
|
+
import { join, resolve } from 'path';
|
|
11
11
|
import { cmdInit, getVersion } from './init.js';
|
|
12
|
+
import { ProgressManager } from './progress.js';
|
|
12
13
|
|
|
13
14
|
// ── CLI 入口 ──
|
|
14
15
|
|
|
@@ -19,15 +20,36 @@ SillySpec CLI — 规范驱动开发工具包
|
|
|
19
20
|
用法:
|
|
20
21
|
sillyspec init 初始化(零交互,自动检测工具)
|
|
21
22
|
[--tool <name>] 只安装指定工具
|
|
22
|
-
[--workspace] 工作区模式
|
|
23
23
|
[--interactive] 交互式引导
|
|
24
24
|
[--dir <path>] 指定目录
|
|
25
|
+
|
|
25
26
|
sillyspec setup [--list] 安装推荐 MCP 工具
|
|
26
27
|
[--list] 查看已安装状态
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
|
|
29
|
+
sillyspec run <stage> 执行阶段步骤(核心命令)
|
|
30
|
+
--done --output "..." 完成当前步骤
|
|
31
|
+
--skip 跳过可选步骤
|
|
32
|
+
--status 查看阶段进度
|
|
33
|
+
--reset 重置阶段
|
|
34
|
+
--change <name> 设置当前变更名
|
|
35
|
+
auto 连续推进 brainstorm→plan→execute→verify
|
|
36
|
+
|
|
37
|
+
可选阶段:
|
|
38
|
+
scan, brainstorm, plan, execute, verify, archive
|
|
39
|
+
quick, explore, status, doctor
|
|
40
|
+
|
|
41
|
+
sillyspec progress <cmd> 进度记录(轻量,不强制顺序)
|
|
42
|
+
init 初始化 progress.json
|
|
43
|
+
show 查看当前进度
|
|
44
|
+
set-stage <stage> 设置当前阶段
|
|
45
|
+
add-step <stage> <name> 添加步骤
|
|
46
|
+
update-step <s> <n> --status <st> [--output <t>]
|
|
47
|
+
complete-stage <stage> 标记阶段完成
|
|
48
|
+
validate 校验并修复
|
|
49
|
+
reset [--stage X] 重置进度
|
|
50
|
+
|
|
51
|
+
sillyspec docs migrate 迁移旧文档到统一结构
|
|
52
|
+
|
|
31
53
|
sillyspec dashboard 启动 Dashboard Web UI
|
|
32
54
|
[--port <number>] 指定端口(默认 3456)
|
|
33
55
|
[--no-open] 不自动打开浏览器
|
|
@@ -38,11 +60,12 @@ SillySpec CLI — 规范驱动开发工具包
|
|
|
38
60
|
|
|
39
61
|
示例:
|
|
40
62
|
sillyspec init
|
|
41
|
-
sillyspec
|
|
42
|
-
sillyspec
|
|
43
|
-
sillyspec
|
|
63
|
+
sillyspec run scan
|
|
64
|
+
sillyspec run brainstorm
|
|
65
|
+
sillyspec run quick
|
|
66
|
+
sillyspec run explore
|
|
67
|
+
sillyspec run brainstorm --done --output "需求已澄清"
|
|
44
68
|
sillyspec setup --list
|
|
45
|
-
sillyspec dashboard
|
|
46
69
|
sillyspec dashboard --port 8080 --no-open
|
|
47
70
|
`);
|
|
48
71
|
}
|
|
@@ -64,7 +87,6 @@ async function main() {
|
|
|
64
87
|
let json = false;
|
|
65
88
|
let targetDir = process.cwd();
|
|
66
89
|
let tool = null;
|
|
67
|
-
let workspace = false;
|
|
68
90
|
let interactive = false;
|
|
69
91
|
const filteredArgs = [];
|
|
70
92
|
|
|
@@ -77,8 +99,6 @@ async function main() {
|
|
|
77
99
|
} else if (args[i] === '--tool' && args[i + 1]) {
|
|
78
100
|
tool = args[i + 1];
|
|
79
101
|
i++;
|
|
80
|
-
} else if (args[i] === '--workspace' || args[i] === '-w') {
|
|
81
|
-
workspace = true;
|
|
82
102
|
} else if (args[i] === '--interactive' || args[i] === '-i') {
|
|
83
103
|
interactive = true;
|
|
84
104
|
} else if (args[i] === '--list' || args[i] === '-l') {
|
|
@@ -89,8 +109,18 @@ async function main() {
|
|
|
89
109
|
}
|
|
90
110
|
|
|
91
111
|
const command = filteredArgs[0];
|
|
112
|
+
// 支持 sillyspec init /path/to/project 语法:如果第二个参数看起来像路径,当作 targetDir
|
|
113
|
+
if (command === 'init' && filteredArgs[1] && !filteredArgs[1].startsWith('-')) {
|
|
114
|
+
targetDir = resolve(filteredArgs[1]);
|
|
115
|
+
filteredArgs.splice(1, 1);
|
|
116
|
+
}
|
|
92
117
|
const dir = targetDir;
|
|
93
118
|
|
|
119
|
+
if (command === 'init' && !existsSync(dir)) {
|
|
120
|
+
const { mkdirSync } = await import('fs');
|
|
121
|
+
mkdirSync(dir, { recursive: true });
|
|
122
|
+
}
|
|
123
|
+
|
|
94
124
|
if (!existsSync(dir)) {
|
|
95
125
|
console.error(`❌ 目录不存在: ${dir}`);
|
|
96
126
|
process.exit(1);
|
|
@@ -98,21 +128,110 @@ async function main() {
|
|
|
98
128
|
|
|
99
129
|
switch (command) {
|
|
100
130
|
case 'init':
|
|
101
|
-
await cmdInit(dir, { tool,
|
|
131
|
+
await cmdInit(dir, { tool, interactive });
|
|
102
132
|
break;
|
|
103
133
|
case 'setup':
|
|
104
134
|
const setupList = filteredArgs.includes('--list') || filteredArgs.includes('-l');
|
|
105
135
|
await (await import('./setup.js')).cmdSetup(dir, { json, list: setupList });
|
|
106
136
|
break;
|
|
107
|
-
case '
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
137
|
+
case 'progress': {
|
|
138
|
+
const pm = new ProgressManager();
|
|
139
|
+
const subCommand = filteredArgs[1];
|
|
140
|
+
const stageIdx = filteredArgs.indexOf('--stage');
|
|
141
|
+
const stage = stageIdx >= 0 && filteredArgs[stageIdx + 1] ? filteredArgs[stageIdx + 1] : null;
|
|
142
|
+
|
|
143
|
+
switch (subCommand) {
|
|
144
|
+
case 'init':
|
|
145
|
+
pm.init(dir);
|
|
146
|
+
break;
|
|
147
|
+
case 'status':
|
|
148
|
+
case 'show':
|
|
149
|
+
pm.show(dir);
|
|
150
|
+
break;
|
|
151
|
+
case 'validate':
|
|
152
|
+
await pm.validate(dir);
|
|
153
|
+
break;
|
|
154
|
+
case 'reset':
|
|
155
|
+
pm.reset(dir, stage);
|
|
156
|
+
break;
|
|
157
|
+
case 'set-stage': {
|
|
158
|
+
const setStageName = filteredArgs[2];
|
|
159
|
+
if (!setStageName) { console.log('❌ 用法: sillyspec progress set-stage <stage>'); break; }
|
|
160
|
+
pm.setStage(dir, setStageName);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case 'add-step': {
|
|
164
|
+
const addStepStage = filteredArgs[2];
|
|
165
|
+
const addStepName = filteredArgs[3];
|
|
166
|
+
if (!addStepStage || !addStepName) { console.log('❌ 用法: sillyspec progress add-step <stage> <step-name>'); break; }
|
|
167
|
+
pm.addStep(dir, addStepStage, addStepName);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case 'update-step': {
|
|
171
|
+
const updStepStage = filteredArgs[2];
|
|
172
|
+
const updStepName = filteredArgs[3];
|
|
173
|
+
if (!updStepStage || !updStepName) { console.log('❌ 用法: sillyspec progress update-step <stage> <step-name> --status <status> [--output <text>]'); break; }
|
|
174
|
+
// Parse --status and --output from args
|
|
175
|
+
let updStatus = null, updOutput = undefined;
|
|
176
|
+
for (let ai = 0; ai < args.length; ai++) {
|
|
177
|
+
if (args[ai] === '--status' && args[ai + 1]) { updStatus = args[ai + 1]; ai++; }
|
|
178
|
+
if (args[ai] === '--output' && args[ai + 1]) { updOutput = args[ai + 1]; ai++; }
|
|
179
|
+
}
|
|
180
|
+
pm.updateStep(dir, updStepStage, updStepName, { status: updStatus, output: updOutput });
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
case 'complete-stage': {
|
|
184
|
+
const compStageName = filteredArgs[2];
|
|
185
|
+
if (!compStageName) { console.log('❌ 用法: sillyspec progress complete-stage <stage>'); break; }
|
|
186
|
+
pm.completeStage(dir, compStageName);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case 'batch': {
|
|
190
|
+
if (filteredArgs.includes('--status')) {
|
|
191
|
+
const bp = pm.readBatchProgress(dir);
|
|
192
|
+
if (!bp) { console.log('📭 无批量进度数据'); break; }
|
|
193
|
+
const line = pm._renderBatchProgress(bp);
|
|
194
|
+
console.log(line || '📭 无批量进度数据');
|
|
195
|
+
console.log(JSON.stringify(bp, null, 2));
|
|
196
|
+
} else {
|
|
197
|
+
let batchData = {};
|
|
198
|
+
const a = args;
|
|
199
|
+
for (let i = 0; i < a.length; i++) {
|
|
200
|
+
if (a[i] === '--total' && a[i + 1]) { batchData.total = parseInt(a[i + 1]); i++; }
|
|
201
|
+
if (a[i] === '--completed' && a[i + 1]) { batchData.completed = parseInt(a[i + 1]); i++; }
|
|
202
|
+
if (a[i] === '--failed' && a[i + 1]) { batchData.failed = parseInt(a[i + 1]); i++; }
|
|
203
|
+
if (a[i] === '--skipped' && a[i + 1]) { batchData.skipped = parseInt(a[i + 1]); i++; }
|
|
204
|
+
}
|
|
205
|
+
if (Object.keys(batchData).length === 0) {
|
|
206
|
+
console.log('用法: sillyspec progress batch --total 100 --completed 73');
|
|
207
|
+
console.log(' sillyspec progress batch --status');
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
pm.updateBatchProgress(dir, batchData);
|
|
211
|
+
console.log('✅ 批量进度已更新');
|
|
212
|
+
}
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
default:
|
|
216
|
+
console.log('用法: sillyspec progress <init|show|validate|reset|set-stage|add-step|update-step|complete-stage>');
|
|
217
|
+
}
|
|
111
218
|
break;
|
|
112
219
|
}
|
|
113
|
-
case '
|
|
114
|
-
|
|
220
|
+
case 'docs': {
|
|
221
|
+
const docsSubCmd = filteredArgs[1];
|
|
222
|
+
if (docsSubCmd === 'migrate') {
|
|
223
|
+
const { migrateDocs } = await import('./migrate.js');
|
|
224
|
+
migrateDocs(dir);
|
|
225
|
+
} else {
|
|
226
|
+
console.log('用法: sillyspec docs migrate');
|
|
227
|
+
}
|
|
115
228
|
break;
|
|
229
|
+
}
|
|
230
|
+
case 'run': {
|
|
231
|
+
const { runCommand } = await import('./run.js')
|
|
232
|
+
await runCommand(filteredArgs.slice(1), dir)
|
|
233
|
+
break
|
|
234
|
+
}
|
|
116
235
|
case 'dashboard': {
|
|
117
236
|
// Parse dashboard options
|
|
118
237
|
let port = 3456;
|