sillyspec 3.20.1 → 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 (209) 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 +2 -8
  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 -685
  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 -2920
  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 -468
  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/.npmrc-tmp +0 -1
  131. package/CLAUDE.md +0 -18
  132. package/docs/brainstorm-plan-contract.md +0 -64
  133. package/docs/plan-execute-contract.md +0 -123
  134. package/docs/platform-scan-protocol.md +0 -298
  135. package/docs/revision-mode.md +0 -115
  136. package/docs/sillyspec/file-lifecycle/known-implementation-gaps.md +0 -99
  137. package/docs/sillyspec/file-lifecycle/platform-workflows-sync.md +0 -218
  138. package/docs/sillyspec/file-lifecycle/stage-artifacts.md +0 -167
  139. package/docs/sillyspec/file-lifecycle/storage-and-state.md +0 -148
  140. package/docs/sillyspec/file-lifecycle/worktree-and-guard.md +0 -193
  141. package/docs/sillyspec/file-lifecycle.md +0 -125
  142. package/docs/workflow-contract-regression.md +0 -106
  143. package/docs/worktree-isolation.md +0 -252
  144. package/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  145. package/packages/dashboard/dist/prototype-dashboard.html +0 -836
  146. package/packages/dashboard/dist/prototype-overview.html +0 -256
  147. package/packages/dashboard/public/prototype-dashboard.html +0 -836
  148. package/packages/dashboard/public/prototype-overview.html +0 -256
  149. package/packages/dashboard/src/components/HResizeHandle.vue +0 -48
  150. package/packages/dashboard/src/components/ProjectCard.vue +0 -187
  151. package/packages/dashboard/src/components/VResizeHandle.vue +0 -61
  152. package/packages/dashboard/src/composables/useLayout.js +0 -131
  153. package/src/brainstorm-postcheck.js +0 -158
  154. package/src/change-list.js +0 -52
  155. package/src/change-risk-profile.js +0 -352
  156. package/src/classify-change.js +0 -73
  157. package/src/constants.js +0 -70
  158. package/src/contract-matrix.js +0 -278
  159. package/src/db.js +0 -201
  160. package/src/endpoint-extractor.js +0 -315
  161. package/src/hooks/claude-pre-tool-use.cjs +0 -125
  162. package/src/hooks/worktree-guard.js +0 -761
  163. package/src/knowledge-match.js +0 -130
  164. package/src/modules.js +0 -482
  165. package/src/scan-postcheck.js +0 -380
  166. package/src/stage-contract.js +0 -700
  167. package/src/stages/brainstorm-auto.js +0 -229
  168. package/src/stages/explore.js +0 -34
  169. package/src/stages/knowledge.js +0 -498
  170. package/src/stages/plan-postcheck.js +0 -513
  171. package/src/sync.js +0 -497
  172. package/src/task-review.js +0 -346
  173. package/src/workflow.js +0 -785
  174. package/src/worktree-apply.js +0 -549
  175. package/src/worktree.js +0 -932
  176. package/templates/workflows/archive-impact.yaml +0 -79
  177. package/templates/workflows/scan-docs.yaml +0 -132
  178. package/test/brainstorm-plan-contract.test.mjs +0 -273
  179. package/test/check-syntax.mjs +0 -26
  180. package/test/cli-top-level-aliases.test.mjs +0 -174
  181. package/test/contract-artifacts.test.mjs +0 -323
  182. package/test/decision-supersede.test.mjs +0 -277
  183. package/test/knowledge-match.test.mjs +0 -231
  184. package/test/plan-execute-contract.test.mjs +0 -330
  185. package/test/plan-optimization.test.mjs +0 -572
  186. package/test/platform-artifacts.test.mjs +0 -190
  187. package/test/platform-failure-samples.test.mjs +0 -199
  188. package/test/platform-recovery-chain.test.mjs +0 -179
  189. package/test/platform-recovery.test.mjs +0 -167
  190. package/test/platform-scan-p0.test.mjs +0 -175
  191. package/test/revision-v1.test.mjs +0 -1145
  192. package/test/run-sanitize-project-name.test.mjs +0 -51
  193. package/test/run-scan-postcheck-fail.test.mjs +0 -64
  194. package/test/run-scan-project-parse.test.mjs +0 -77
  195. package/test/run-tests.mjs +0 -48
  196. package/test/scan-docs-yaml-placeholders.test.mjs +0 -84
  197. package/test/scan-knowledge.test.mjs +0 -175
  198. package/test/scan-paths.test.mjs +0 -68
  199. package/test/scan-postcheck-project-priority.test.mjs +0 -85
  200. package/test/scan-postcheck.test.mjs +0 -183
  201. package/test/scan-workflow-anyfailed-block.test.mjs +0 -52
  202. package/test/spec-dir.test.mjs +0 -206
  203. package/test/stage-contract-failed-post-check.test.mjs +0 -102
  204. package/test/stage-contract.test.mjs +0 -299
  205. package/test/stage-definitions.test.mjs +0 -39
  206. package/test/wait-gates.test.mjs +0 -501
  207. package/test/workflow-spec-base.test.mjs +0 -142
  208. package/test/worktree-guard.test.mjs +0 -136
  209. 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>