sillyspec 3.20.2 → 3.20.3

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 (208) hide show
  1. package/.claude/skills/sillyspec-archive/SKILL.md +1 -5
  2. package/.claude/skills/sillyspec-auto/SKILL.md +2 -8
  3. package/.claude/skills/sillyspec-brainstorm/SKILL.md +1 -28
  4. package/.claude/skills/sillyspec-commit/SKILL.md +3 -4
  5. package/.claude/skills/sillyspec-continue/SKILL.md +4 -5
  6. package/.claude/skills/sillyspec-doctor/SKILL.md +3 -12
  7. package/.claude/skills/sillyspec-execute/SKILL.md +2 -15
  8. package/.claude/skills/sillyspec-explore/SKILL.md +1 -14
  9. package/.claude/skills/sillyspec-plan/SKILL.md +36 -5
  10. package/.claude/skills/sillyspec-propose/SKILL.md +0 -4
  11. package/.claude/skills/sillyspec-quick/SKILL.md +1 -5
  12. package/.claude/skills/sillyspec-resume/SKILL.md +66 -23
  13. package/.claude/skills/sillyspec-scan/SKILL.md +1 -5
  14. package/.claude/skills/sillyspec-state/SKILL.md +8 -8
  15. package/.claude/skills/sillyspec-status/SKILL.md +1 -5
  16. package/.claude/skills/sillyspec-verify/SKILL.md +1 -5
  17. package/.claude/skills/sillyspec-workspace/SKILL.md +3 -11
  18. package/.sillyspec/changes/archive/2026-04-08-derive-state/design.md +97 -0
  19. package/.sillyspec/changes/archive/2026-04-08-derive-state/plan.md +51 -0
  20. package/.sillyspec/changes/archive/2026-04-08-derive-state/proposal.md +29 -0
  21. package/.sillyspec/changes/archive/2026-04-08-derive-state/requirements.md +34 -0
  22. package/.sillyspec/changes/archive/2026-04-08-derive-state/tasks.md +13 -0
  23. package/.sillyspec/changes/archive/2026-04-08-derive-state/verify-result.md +43 -0
  24. package/.sillyspec/changes/auto-mode/design.md +50 -0
  25. package/.sillyspec/changes/auto-mode/proposal.md +19 -0
  26. package/.sillyspec/changes/auto-mode/requirements.md +21 -0
  27. package/.sillyspec/changes/auto-mode/tasks.md +7 -0
  28. package/.sillyspec/changes/brainstorm-archive/2026-04-05-dashboard-design.md +206 -0
  29. package/.sillyspec/changes/brainstorm-archive/2026-04-05-unified-docs-design.md +199 -0
  30. package/.sillyspec/changes/dashboard/design.md +219 -0
  31. package/.sillyspec/changes/dashboard/design.md.braindraft +206 -0
  32. package/.sillyspec/changes/run-command-design/design.md +1230 -0
  33. package/.sillyspec/changes/unified-docs-design/design.md +199 -0
  34. package/.sillyspec/docs/sillyspec/scan/.gitkeep +0 -0
  35. package/.sillyspec/knowledge/INDEX.md +8 -0
  36. package/.sillyspec/knowledge/uncategorized.md +3 -0
  37. package/.sillyspec/plans/2026-04-05-dashboard.md +737 -0
  38. package/.sillyspec/projects/sillyspec.yaml +3 -0
  39. package/README.md +11 -13
  40. package/SKILL.md +40 -44
  41. package/dist/steps/brainstorm/01-load-context.md +30 -0
  42. package/dist/steps/brainstorm/02-reuse-check.md +6 -0
  43. package/dist/steps/brainstorm/03-prototype-analysis.md +11 -0
  44. package/dist/steps/brainstorm/04-module-split.md +23 -0
  45. package/dist/steps/brainstorm/05-dialog-explore.md +8 -0
  46. package/dist/steps/brainstorm/06-propose-approaches.md +3 -0
  47. package/dist/steps/brainstorm/07-present-design.md +3 -0
  48. package/dist/steps/brainstorm/08-write-design.md +21 -0
  49. package/dist/steps/brainstorm/09-self-review.md +15 -0
  50. package/dist/steps/brainstorm/10-user-confirm.md +3 -0
  51. package/dist/steps/brainstorm/11-output-spec.md +7 -0
  52. package/dist/steps/brainstorm/manifest.yaml +26 -0
  53. package/dist/steps/execute/01-load-context.md +41 -0
  54. package/dist/steps/execute/02-scan-conventions.md +47 -0
  55. package/dist/steps/execute/03-skill-mcp.md +19 -0
  56. package/dist/steps/execute/04-assign-task.md +22 -0
  57. package/dist/steps/execute/04b-prompt-template.md +54 -0
  58. package/dist/steps/execute/05-write-test.md +7 -0
  59. package/dist/steps/execute/06-write-code.md +8 -0
  60. package/dist/steps/execute/07-run-test.md +26 -0
  61. package/dist/steps/execute/08-fix-issues.md +28 -0
  62. package/dist/steps/execute/09-next-task.md +33 -0
  63. package/dist/steps/execute/manifest.yaml +28 -0
  64. package/dist/steps/plan/01-load-context.md +22 -0
  65. package/dist/steps/plan/02-anchor-confirm.md +1 -0
  66. package/dist/steps/plan/03-expand-tasks.md +33 -0
  67. package/dist/steps/plan/04-mark-order.md +15 -0
  68. package/dist/steps/plan/05-e2e-planning.md +17 -0
  69. package/dist/steps/plan/06-self-check.md +16 -0
  70. package/dist/steps/plan/07-save.md +1 -0
  71. package/dist/steps/plan/manifest.yaml +18 -0
  72. package/dist/steps/scan/01-env-detect.md +51 -0
  73. package/dist/steps/scan/02-tech-stack.md +16 -0
  74. package/dist/steps/scan/03-conventions.md +16 -0
  75. package/dist/steps/scan/04-structure.md +19 -0
  76. package/dist/steps/scan/05-quality.md +18 -0
  77. package/dist/steps/scan/06-complete.md +49 -0
  78. package/dist/steps/scan/manifest.yaml +16 -0
  79. package/dist/steps/verify/01-load-specs.md +28 -0
  80. package/dist/steps/verify/02-check-tasks.md +1 -0
  81. package/dist/steps/verify/03-check-design.md +6 -0
  82. package/dist/steps/verify/04-run-tests.md +7 -0
  83. package/dist/steps/verify/05-e2e-tests.md +27 -0
  84. package/dist/steps/verify/05b-e2e-fix.md +33 -0
  85. package/dist/steps/verify/06-code-quality.md +25 -0
  86. package/dist/steps/verify/07-lint-check.md +27 -0
  87. package/dist/steps/verify/08-output-report.md +14 -0
  88. package/dist/steps/verify/manifest.yaml +22 -0
  89. package/package.json +1 -7
  90. package/packages/dashboard/dist/assets/{index-Bq_Z2hne.js → index-D1EVTLmc.js} +1264 -1264
  91. package/packages/dashboard/dist/assets/index-DGe8CqeP.css +1 -0
  92. package/packages/dashboard/dist/index.html +2 -2
  93. package/packages/dashboard/package-lock.json +6 -6
  94. package/packages/dashboard/server/executor.js +1 -1
  95. package/packages/dashboard/server/index.js +18 -98
  96. package/packages/dashboard/server/parser.js +71 -139
  97. package/packages/dashboard/server/watcher.js +6 -14
  98. package/packages/dashboard/src/App.vue +185 -418
  99. package/packages/dashboard/src/components/ActionBar.vue +1 -10
  100. package/packages/dashboard/src/components/CommandPalette.vue +1 -5
  101. package/packages/dashboard/src/components/DocPreview.vue +8 -105
  102. package/packages/dashboard/src/components/DocTree.vue +19 -75
  103. package/packages/dashboard/src/components/PipelineStage.vue +2 -22
  104. package/packages/dashboard/src/components/PipelineView.vue +5 -32
  105. package/packages/dashboard/src/components/ProjectOverview.vue +139 -113
  106. package/packages/dashboard/src/components/StageBadge.vue +3 -17
  107. package/packages/dashboard/src/components/StepCard.vue +2 -7
  108. package/packages/dashboard/src/composables/useDashboard.js +0 -28
  109. package/src/derive.js +147 -0
  110. package/src/index.js +40 -688
  111. package/src/init.js +63 -119
  112. package/src/migrate.js +7 -7
  113. package/src/progress.js +248 -1474
  114. package/src/run.js +302 -3008
  115. package/src/setup.js +64 -2
  116. package/src/stages/archive.js +17 -123
  117. package/src/stages/brainstorm.js +48 -454
  118. package/src/stages/doctor.js +46 -99
  119. package/src/stages/execute.js +59 -420
  120. package/src/stages/index.js +18 -12
  121. package/src/stages/plan.js +189 -492
  122. package/src/stages/propose.js +11 -70
  123. package/src/stages/quick.js +13 -52
  124. package/src/stages/scan.js +68 -485
  125. package/src/stages/status.js +1 -1
  126. package/src/stages/verify.js +16 -203
  127. package/src/step.js +543 -0
  128. package/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  129. package/.husky/pre-push +0 -13
  130. package/CLAUDE.md +0 -18
  131. package/docs/brainstorm-plan-contract.md +0 -64
  132. package/docs/plan-execute-contract.md +0 -123
  133. package/docs/platform-scan-protocol.md +0 -298
  134. package/docs/revision-mode.md +0 -115
  135. package/docs/sillyspec/file-lifecycle/known-implementation-gaps.md +0 -99
  136. package/docs/sillyspec/file-lifecycle/platform-workflows-sync.md +0 -218
  137. package/docs/sillyspec/file-lifecycle/stage-artifacts.md +0 -167
  138. package/docs/sillyspec/file-lifecycle/storage-and-state.md +0 -148
  139. package/docs/sillyspec/file-lifecycle/worktree-and-guard.md +0 -193
  140. package/docs/sillyspec/file-lifecycle.md +0 -125
  141. package/docs/workflow-contract-regression.md +0 -106
  142. package/docs/worktree-isolation.md +0 -252
  143. package/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  144. package/packages/dashboard/dist/prototype-dashboard.html +0 -836
  145. package/packages/dashboard/dist/prototype-overview.html +0 -256
  146. package/packages/dashboard/public/prototype-dashboard.html +0 -836
  147. package/packages/dashboard/public/prototype-overview.html +0 -256
  148. package/packages/dashboard/src/components/HResizeHandle.vue +0 -48
  149. package/packages/dashboard/src/components/ProjectCard.vue +0 -187
  150. package/packages/dashboard/src/components/VResizeHandle.vue +0 -61
  151. package/packages/dashboard/src/composables/useLayout.js +0 -131
  152. package/src/brainstorm-postcheck.js +0 -158
  153. package/src/change-list.js +0 -52
  154. package/src/change-risk-profile.js +0 -352
  155. package/src/classify-change.js +0 -73
  156. package/src/constants.js +0 -70
  157. package/src/contract-matrix.js +0 -278
  158. package/src/db.js +0 -201
  159. package/src/endpoint-extractor.js +0 -315
  160. package/src/hooks/claude-pre-tool-use.cjs +0 -125
  161. package/src/hooks/worktree-guard.js +0 -761
  162. package/src/knowledge-match.js +0 -130
  163. package/src/modules.js +0 -482
  164. package/src/scan-postcheck.js +0 -383
  165. package/src/stage-contract.js +0 -700
  166. package/src/stages/brainstorm-auto.js +0 -229
  167. package/src/stages/explore.js +0 -34
  168. package/src/stages/knowledge.js +0 -498
  169. package/src/stages/plan-postcheck.js +0 -513
  170. package/src/sync.js +0 -497
  171. package/src/task-review.js +0 -346
  172. package/src/workflow.js +0 -785
  173. package/src/worktree-apply.js +0 -549
  174. package/src/worktree.js +0 -932
  175. package/templates/workflows/archive-impact.yaml +0 -79
  176. package/templates/workflows/scan-docs.yaml +0 -132
  177. package/test/brainstorm-plan-contract.test.mjs +0 -273
  178. package/test/check-syntax.mjs +0 -26
  179. package/test/cli-top-level-aliases.test.mjs +0 -174
  180. package/test/contract-artifacts.test.mjs +0 -323
  181. package/test/decision-supersede.test.mjs +0 -277
  182. package/test/knowledge-match.test.mjs +0 -231
  183. package/test/plan-execute-contract.test.mjs +0 -330
  184. package/test/plan-optimization.test.mjs +0 -572
  185. package/test/platform-artifacts.test.mjs +0 -190
  186. package/test/platform-failure-samples.test.mjs +0 -199
  187. package/test/platform-recovery-chain.test.mjs +0 -179
  188. package/test/platform-recovery.test.mjs +0 -167
  189. package/test/platform-scan-p0.test.mjs +0 -175
  190. package/test/revision-v1.test.mjs +0 -1145
  191. package/test/run-sanitize-project-name.test.mjs +0 -51
  192. package/test/run-scan-postcheck-fail.test.mjs +0 -64
  193. package/test/run-scan-project-parse.test.mjs +0 -200
  194. package/test/run-tests.mjs +0 -48
  195. package/test/scan-docs-yaml-placeholders.test.mjs +0 -84
  196. package/test/scan-knowledge.test.mjs +0 -175
  197. package/test/scan-paths.test.mjs +0 -68
  198. package/test/scan-postcheck-project-priority.test.mjs +0 -85
  199. package/test/scan-postcheck.test.mjs +0 -197
  200. package/test/scan-workflow-anyfailed-block.test.mjs +0 -52
  201. package/test/spec-dir.test.mjs +0 -206
  202. package/test/stage-contract-failed-post-check.test.mjs +0 -102
  203. package/test/stage-contract.test.mjs +0 -299
  204. package/test/stage-definitions.test.mjs +0 -39
  205. package/test/wait-gates.test.mjs +0 -501
  206. package/test/workflow-spec-base.test.mjs +0 -142
  207. package/test/worktree-guard.test.mjs +0 -136
  208. package/test/worktree-native-overlay.test.mjs +0 -188
@@ -78,16 +78,7 @@ function getProjectStatus() {
78
78
 
79
79
  function stageLabel() {
80
80
  const stage = props.project?.state?.currentStage
81
- const labels = {
82
- scan: '代码扫描',
83
- brainstorm: '头脑风暴',
84
- plan: '规划',
85
- execute: '执行',
86
- verify: '验证',
87
- archive: '归档',
88
- quick: '快速任务',
89
- explore: '自由探索'
90
- }
81
+ const labels = { 'brainstorm': '头脑风暴', 'plan': '规划', 'execute': '执行', 'verify': '验证' }
91
82
  return labels[stage] || stage || '未知'
92
83
  }
93
84
  </script>
@@ -58,14 +58,10 @@ const searchInput = ref(null)
58
58
  const selectedIndex = ref(0)
59
59
 
60
60
  const stageNames = [
61
- { id: 'scan', name: '代码扫描' },
62
61
  { id: 'brainstorm', name: '头脑风暴' },
63
62
  { id: 'plan', name: '规划' },
64
63
  { id: 'execute', name: '执行' },
65
- { id: 'verify', name: '验证' },
66
- { id: 'archive', name: '归档' },
67
- { id: 'quick', name: '快速任务' },
68
- { id: 'explore', name: '自由探索' }
64
+ { id: 'verify', name: '验证' }
69
65
  ]
70
66
 
71
67
  const filteredItems = computed(() => {
@@ -1,59 +1,29 @@
1
1
  <template>
2
- <div class="doc-preview-shell">
3
- <div v-if="!content && !loading" class="doc-empty">
4
- <p>选择一个文档查看内容</p>
2
+ <div class="h-full overflow-y-auto px-6 py-4">
3
+ <div v-if="!content && !loading" class="flex items-center justify-center h-full">
4
+ <p class="text-[12px] font-[JetBrains_Mono,monospace]" style="color: #636366;">选择一个文档查看内容</p>
5
5
  </div>
6
- <div v-else-if="loading" class="doc-empty">
7
- <p>加载中...</p>
6
+ <div v-else-if="loading" class="flex items-center justify-center h-full">
7
+ <p class="text-[12px] font-[JetBrains_Mono,monospace]" style="color: #636366;">加载中...</p>
8
8
  </div>
9
- <template v-else>
10
- <div class="doc-toolbar">
11
- <div class="doc-title" :title="fileTitle">{{ fileTitle }}</div>
12
- <n-button size="tiny" type="primary" @click="isModalOpen = true">弹窗阅读</n-button>
13
- </div>
14
- <div class="doc-preview-scroll">
15
- <div class="doc-preview" v-html="renderedContent"></div>
16
- </div>
17
- </template>
18
-
19
- <n-modal
20
- v-model:show="isModalOpen"
21
- preset="card"
22
- :title="fileTitle"
23
- style="width: min(920px, calc(100vw - 48px));"
24
- >
25
- <div class="doc-modal-body">
26
- <div class="doc-preview doc-preview-large" v-html="renderedContent"></div>
27
- </div>
28
- </n-modal>
9
+ <div v-else class="doc-preview" v-html="renderedContent"></div>
29
10
  </div>
30
11
  </template>
31
12
 
32
13
  <script setup>
33
- import { computed, ref, watch } from 'vue'
14
+ import { computed } from 'vue'
34
15
  import { marked } from 'marked'
35
16
 
36
17
  const props = defineProps({
37
18
  content: { type: String, default: '' },
38
- loading: { type: Boolean, default: false },
39
- selectedFile: { type: Object, default: null }
19
+ loading: { type: Boolean, default: false }
40
20
  })
41
21
 
42
- const isModalOpen = ref(false)
43
-
44
22
  marked.setOptions({
45
23
  breaks: true,
46
24
  gfm: true
47
25
  })
48
26
 
49
- watch(() => props.selectedFile?.path, () => {
50
- isModalOpen.value = false
51
- })
52
-
53
- const fileTitle = computed(() => {
54
- return props.selectedFile?.title || props.selectedFile?.name || '文档'
55
- })
56
-
57
27
  const renderedContent = computed(() => {
58
28
  if (!props.content) return ''
59
29
  return marked.parse(props.content)
@@ -61,69 +31,10 @@ const renderedContent = computed(() => {
61
31
  </script>
62
32
 
63
33
  <style scoped>
64
- .doc-preview-shell {
65
- height: 100%;
66
- min-height: 0;
67
- display: flex;
68
- flex-direction: column;
69
- background: #FFFFFF;
70
- }
71
-
72
- .doc-empty {
73
- height: 100%;
74
- display: flex;
75
- align-items: center;
76
- justify-content: center;
77
- padding: 24px;
78
- text-align: center;
79
- font-size: 12px;
80
- color: #636366;
81
- font-family: 'JetBrains Mono', monospace;
82
- }
83
-
84
- .doc-toolbar {
85
- flex-shrink: 0;
86
- display: flex;
87
- align-items: center;
88
- justify-content: space-between;
89
- gap: 12px;
90
- padding: 10px 14px;
91
- border-bottom: 1px solid #F0F0F3;
92
- }
93
-
94
- .doc-title {
95
- min-width: 0;
96
- overflow: hidden;
97
- text-overflow: ellipsis;
98
- white-space: nowrap;
99
- font-size: 12px;
100
- font-weight: 600;
101
- color: #1C1C1E;
102
- }
103
-
104
- .doc-preview-scroll {
105
- flex: 1;
106
- min-height: 0;
107
- overflow: auto;
108
- padding: 14px 16px 22px;
109
- }
110
-
111
- .doc-modal-body {
112
- max-height: min(72vh, 760px);
113
- overflow: auto;
114
- padding-right: 4px;
115
- }
116
-
117
34
  .doc-preview {
118
35
  font-size: 13px;
119
36
  line-height: 1.7;
120
37
  color: #374151;
121
- overflow-wrap: anywhere;
122
- }
123
-
124
- .doc-preview-large {
125
- font-size: 14px;
126
- line-height: 1.75;
127
38
  }
128
39
 
129
40
  .doc-preview :deep(h1) {
@@ -135,10 +46,6 @@ const renderedContent = computed(() => {
135
46
  padding-bottom: 8px;
136
47
  }
137
48
 
138
- .doc-preview-large :deep(h1) {
139
- font-size: 22px;
140
- }
141
-
142
49
  .doc-preview :deep(h2) {
143
50
  color: #1C1C1E;
144
51
  font-size: 15px;
@@ -146,10 +53,6 @@ const renderedContent = computed(() => {
146
53
  margin: 20px 0 10px;
147
54
  }
148
55
 
149
- .doc-preview-large :deep(h2) {
150
- font-size: 17px;
151
- }
152
-
153
56
  .doc-preview :deep(h3) {
154
57
  color: #D97706;
155
58
  font-size: 14px;
@@ -1,31 +1,22 @@
1
1
  <template>
2
- <div class="doc-tree">
3
- <div class="doc-tree-search">
4
- <n-input
5
- v-model:value="query"
6
- size="small"
7
- clearable
8
- placeholder="搜索文档"
9
- />
10
- </div>
11
-
2
+ <div class="flex flex-col h-full">
12
3
  <n-empty v-if="groups.length === 0" description="暂无文档" style="margin: auto;" />
13
- <n-empty v-else-if="treeData.length === 0" description="无匹配文档" style="margin: auto;" />
14
4
  <n-tree
15
5
  v-else
16
- class="doc-tree-list"
17
6
  :data="treeData"
18
7
  :selected-keys="selectedKeys"
19
8
  :default-expand-all="true"
20
9
  selectable
21
10
  block-line
22
11
  @update:selected-keys="handleSelect"
12
+ style="padding: 8px 12px;"
23
13
  />
24
14
  </div>
25
15
  </template>
26
16
 
27
17
  <script setup>
28
- import { computed, ref } from 'vue'
18
+ import { computed, h } from 'vue'
19
+ import { NIcon } from 'naive-ui'
29
20
 
30
21
  const props = defineProps({
31
22
  groups: { type: Array, default: () => [] },
@@ -33,48 +24,30 @@ const props = defineProps({
33
24
  })
34
25
 
35
26
  const emit = defineEmits(['select-file'])
36
- const query = ref('')
37
27
 
38
28
  const selectedKeys = computed(() => {
39
29
  return props.selectedFile?.path ? [props.selectedFile.path] : []
40
30
  })
41
31
 
42
32
  const groupIcons = {
43
- design: '📋',
44
- plan: '🧾',
45
- archive: '📦',
46
- changes: '⚙️',
47
- scan: '🔍',
48
- quicklog: '⚡'
33
+ '设计文档': '📋',
34
+ '实现计划': '📐',
35
+ '归档': '📦',
36
+ ' proposals': '📝'
49
37
  }
50
38
 
51
39
  const treeData = computed(() => {
52
- const keyword = query.value.trim().toLowerCase()
53
-
54
- return props.groups
55
- .map(group => {
56
- const groupLabel = group.project ? `${group.label} (${group.project})` : group.label
57
- const groupMatched = !keyword || groupLabel.toLowerCase().includes(keyword)
58
- const files = group.files.filter(file => {
59
- if (groupMatched) return true
60
- return `${file.title || ''} ${file.name || ''}`.toLowerCase().includes(keyword)
61
- })
62
-
63
- if (files.length === 0) return null
64
-
65
- return {
66
- key: `group-${group.key}`,
67
- label: groupLabel,
68
- prefix: () => groupIcons[group.key] || '📄',
69
- children: files.map(file => ({
70
- key: file.path,
71
- label: file.title || file.name,
72
- prefix: () => '📄',
73
- data: file
74
- }))
75
- }
76
- })
77
- .filter(Boolean)
40
+ return props.groups.map(group => ({
41
+ key: `group-${group.key}`,
42
+ label: group.project ? `${group.label} (${group.project})` : group.label,
43
+ prefix: () => groupIcons[group.label] || '📄',
44
+ children: group.files.map(file => ({
45
+ key: file.path,
46
+ label: file.title,
47
+ prefix: () => '📄',
48
+ data: file
49
+ }))
50
+ }))
78
51
  })
79
52
 
80
53
  function handleSelect(keys, option) {
@@ -83,32 +56,3 @@ function handleSelect(keys, option) {
83
56
  }
84
57
  }
85
58
  </script>
86
-
87
- <style scoped>
88
- .doc-tree {
89
- height: 100%;
90
- min-height: 0;
91
- display: flex;
92
- flex-direction: column;
93
- background: #FFFFFF;
94
- }
95
-
96
- .doc-tree-search {
97
- flex-shrink: 0;
98
- padding: 10px 12px 8px;
99
- border-bottom: 1px solid #F0F0F3;
100
- }
101
-
102
- .doc-tree-list {
103
- flex: 1;
104
- min-height: 0;
105
- overflow: auto;
106
- padding: 8px 12px 14px;
107
- }
108
-
109
- .doc-tree-list :deep(.n-tree-node-content__text) {
110
- white-space: normal;
111
- line-height: 1.35;
112
- overflow-wrap: anywhere;
113
- }
114
- </style>
@@ -24,13 +24,6 @@
24
24
  </div>
25
25
 
26
26
  <!-- Steps -->
27
- <div v-if="status === 'stale' && staleReason" class="mb-2 text-[10px] italic" style="color: #CA8A04;">
28
- ⚠️ {{ staleReason }}
29
- <span v-if="name === 'archive'">(已有归档文件保留但不再可信)</span>
30
- </div>
31
- <div v-if="status === 'revising' && revisionInfo" class="mb-2 text-[10px]" style="color: #7C3AED;">
32
- 🔧 {{ revisionInfo }}
33
- </div>
34
27
  <div class="space-y-1">
35
28
  <div v-if="steps.length === 0" class="text-[11px] italic py-1" style="color: #6B7280;">
36
29
  No steps yet
@@ -59,21 +52,11 @@ const props = defineProps({
59
52
  steps: { type: Array, default: () => [] },
60
53
  status: { type: String, default: 'pending' },
61
54
  isActive: { type: Boolean, default: false },
62
- activeStep: { type: Object, default: null },
63
- staleReason: { type: String, default: '' },
64
- revision: { type: Number, default: 0 },
65
- reopenedFromStep: { type: String, default: '' },
55
+ activeStep: { type: Object, default: null }
66
56
  })
67
57
 
68
58
  const emit = defineEmits(['select-step'])
69
59
 
70
- const revisionInfo = computed(() => {
71
- if (!props.revision) return ''
72
- const parts = [`revision ${props.revision}`]
73
- if (props.reopenedFromStep) parts.push(`from: ${props.reopenedFromStep}`)
74
- return parts.join(', ')
75
- })
76
-
77
60
  const nodeStyle = computed(() => {
78
61
  if (props.isActive) return { background: '#D97706', boxShadow: '0 0 8px rgba(251,191,36,0.4)' }
79
62
  const colors = {
@@ -81,10 +64,7 @@ const nodeStyle = computed(() => {
81
64
  'in-progress': '#D97706',
82
65
  'blocked': '#EA580C',
83
66
  'failed': '#DC2626',
84
- 'pending': '#E5E5EA',
85
- 'revising': '#7C3AED',
86
- 'stale': '#CA8A04',
87
- 'waiting': '#2563EB',
67
+ 'pending': '#E5E5EA'
88
68
  }
89
69
  return { background: colors[props.status] || colors.pending }
90
70
  })
@@ -26,8 +26,6 @@
26
26
 
27
27
  <!-- Stages -->
28
28
  <div v-else class="flex-1 overflow-y-auto px-6 pb-5 space-y-5">
29
- <PipelineStage name="scan" title="代码扫描" :steps="getStageSteps('scan')" :status="getStageStatus('scan')" :is-active="currentStage === 'scan'" :active-step="activeStep" @select-step="handleSelectStep" />
30
- <div v-if="hasStage('brainstorm')" class="flex items-center pl-[3px]"><div class="w-px h-4" style="background: #F0F0F3;" /></div>
31
29
  <PipelineStage name="brainstorm" title="头脑风暴" :steps="getStageSteps('brainstorm')" :status="getStageStatus('brainstorm')" :is-active="currentStage === 'brainstorm'" :active-step="activeStep" @select-step="handleSelectStep" />
32
30
  <div v-if="hasStage('plan')" class="flex items-center pl-[3px]"><div class="w-px h-4" style="background: #F0F0F3;" /></div>
33
31
  <PipelineStage name="plan" title="规划" :steps="getStageSteps('plan')" :status="getStageStatus('plan')" :is-active="currentStage === 'plan'" :active-step="activeStep" @select-step="handleSelectStep" />
@@ -35,8 +33,6 @@
35
33
  <PipelineStage name="execute" title="执行" :steps="getStageSteps('execute')" :status="getStageStatus('execute')" :is-active="currentStage === 'execute'" :active-step="activeStep" @select-step="handleSelectStep" />
36
34
  <div v-if="hasStage('verify')" class="flex items-center pl-[3px]"><div class="w-px h-4" style="background: #F0F0F3;" /></div>
37
35
  <PipelineStage name="verify" title="验证" :steps="getStageSteps('verify')" :status="getStageStatus('verify')" :is-active="currentStage === 'verify'" :active-step="activeStep" @select-step="handleSelectStep" />
38
- <div v-if="hasStage('archive')" class="flex items-center pl-[3px]"><div class="w-px h-4" style="background: #F0F0F3;" /></div>
39
- <PipelineStage name="archive" title="归档" :steps="getStageSteps('archive')" :status="getStageStatus('archive')" :is-active="currentStage === 'archive'" :active-step="activeStep" :stale-reason="getStageStaleReason('archive')" :revision="getStageRevision('archive')" :reopened-from-step="getStageReopenedFromStep('archive')" @select-step="handleSelectStep" />
40
36
  </div>
41
37
 
42
38
  <!-- Activity Log -->
@@ -50,7 +46,7 @@
50
46
  <n-timeline-item
51
47
  v-for="(log, i) in activityLogs"
52
48
  :key="i"
53
- :type="log.status === 'completed' ? 'success' : (log.status === 'stale' ? 'warning' : (log.status === 'revising' ? 'info' : 'default'))"
49
+ :type="log.status === 'completed' ? 'success' : 'warning'"
54
50
  >
55
51
  <template #default>
56
52
  <span class="text-[11px]" style="color: #636366;">{{ log.description }}</span>
@@ -66,12 +62,12 @@
66
62
  </div>
67
63
 
68
64
  <!-- Docs Tab -->
69
- <div v-if="activeTab === 'docs'" class="docs-panel flex-1 flex overflow-hidden">
70
- <div class="docs-tree-pane flex-shrink-0 overflow-hidden" style="border-right: 1px solid #F0F0F3;">
65
+ <div v-if="activeTab === 'docs'" class="flex-1 flex overflow-hidden">
66
+ <div class="w-[200px] flex-shrink-0 overflow-hidden" style="border-right: 1px solid #F0F0F3;">
71
67
  <DocTree :groups="docs.groups" :selected-file="selectedDocFile" @select-file="$emit('select-doc-file', $event)" />
72
68
  </div>
73
69
  <div class="flex-1 overflow-hidden">
74
- <DocPreview :content="docContent" :loading="docLoading" :selected-file="selectedDocFile" />
70
+ <DocPreview :content="docContent" :loading="docLoading" />
75
71
  </div>
76
72
  </div>
77
73
  </div>
@@ -100,14 +96,10 @@ const progress = computed(() => props.project?.state?.progress || {})
100
96
  const stages = computed(() => progress.value.stages || {})
101
97
 
102
98
  const stageNameMap = {
103
- scan: '代码扫描',
104
99
  brainstorm: '头脑风暴',
105
100
  plan: '规划',
106
101
  execute: '执行',
107
- verify: '验证',
108
- archive: '归档',
109
- quick: '快速任务',
110
- explore: '自由探索'
102
+ verify: '验证'
111
103
  }
112
104
 
113
105
  const activityLogs = computed(() => {
@@ -117,8 +109,6 @@ const activityLogs = computed(() => {
117
109
  const label = stageNameMap[name] || name
118
110
  if (data.status === 'completed') logs.push({ time: data.completedAt ? formatTime(data.completedAt) : '--:--', status: 'completed', description: `${label} 已完成` })
119
111
  else if (data.status === 'in-progress') logs.push({ time: '--:--', status: 'in-progress', description: `${label} 运行中` })
120
- else if (data.status === 'revising') logs.push({ time: '--:--', status: 'revising', description: `${label} 修订中 (revision ${data.revision || 1})` })
121
- else if (data.status === 'stale') logs.push({ time: '--:--', status: 'stale', description: `${label} 已失效:${data.staleReason || '上游修订'}` })
122
112
  }
123
113
  return logs.reverse()
124
114
  })
@@ -128,9 +118,6 @@ function hasStage(n) { return !!stages.value[n] }
128
118
  function getStageSteps(n) { return stages.value[n]?.steps || [] }
129
119
  function getStageStatus(n) {
130
120
  const s = stages.value[n]; if (!s) return 'pending'
131
- // 优先用 stage 自身的 status(支持 revising/stale)
132
- if (s.status === 'revising' || s.status === 'stale') return s.status
133
- // 没有明确 status 时从 step 推导
134
121
  const steps = s.steps || []
135
122
  if (steps.some(x => x.status === 'failed')) return 'failed'
136
123
  if (steps.some(x => x.status === 'blocked')) return 'blocked'
@@ -138,19 +125,5 @@ function getStageStatus(n) {
138
125
  if (steps.every(x => x.status === 'completed')) return 'completed'
139
126
  return 'pending'
140
127
  }
141
- function getStageStaleReason(n) { return stages.value[n]?.staleReason || '' }
142
- function getStageRevision(n) { return stages.value[n]?.revision || 0 }
143
- function getStageReopenedFromStep(n) { return stages.value[n]?.reopenedFromStep || '' }
144
128
  function handleSelectStep(step) { emit('select-step', step) }
145
129
  </script>
146
-
147
- <style scoped>
148
- .docs-panel {
149
- min-height: 0;
150
- }
151
-
152
- .docs-tree-pane {
153
- width: clamp(220px, 42%, 320px);
154
- min-width: 180px;
155
- }
156
- </style>