sillyspec 3.7.14 → 3.7.16
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 +77 -0
- package/.claude/skills/sillyspec-brainstorm/SKILL.md +591 -0
- package/.claude/skills/sillyspec-continue/SKILL.md +44 -0
- package/.claude/skills/sillyspec-execute/SKILL.md +233 -0
- package/.claude/skills/sillyspec-explore/SKILL.md +96 -0
- package/.claude/skills/sillyspec-export/SKILL.md +53 -0
- package/.claude/skills/sillyspec-init/SKILL.md +171 -0
- package/.claude/skills/sillyspec-plan/SKILL.md +263 -0
- package/.claude/skills/sillyspec-propose/SKILL.md +248 -0
- package/.claude/skills/sillyspec-quick/SKILL.md +102 -0
- package/.claude/skills/sillyspec-resume/SKILL.md +111 -0
- package/{templates/scan.md → .claude/skills/sillyspec-scan/SKILL.md} +22 -60
- package/.claude/skills/sillyspec-state/SKILL.md +54 -0
- package/.claude/skills/sillyspec-status/SKILL.md +131 -0
- package/.claude/skills/sillyspec-verify/SKILL.md +146 -0
- package/.claude/skills/sillyspec-workspace/SKILL.md +149 -0
- package/.sillyspec/changes/run-command-design/design.md +1230 -0
- package/.sillyspec/docs/sillyspec/scan/.gitkeep +0 -0
- package/.sillyspec/knowledge/INDEX.md +8 -0
- package/.sillyspec/knowledge/uncategorized.md +3 -0
- package/.sillyspec/projects/sillyspec.yaml +3 -0
- package/package.json +1 -1
- package/packages/dashboard/dist/assets/index-Bx0cgoK_.js +7446 -0
- package/packages/dashboard/dist/assets/index-DbkUSsNO.css +1 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package-lock.json +220 -0
- package/packages/dashboard/package.json +8 -5
- package/packages/dashboard/server/index.js +91 -3
- package/packages/dashboard/server/parser.js +252 -28
- package/packages/dashboard/src/App.vue +54 -8
- package/packages/dashboard/src/components/ActionBar.vue +23 -39
- package/packages/dashboard/src/components/CommandPalette.vue +40 -65
- package/packages/dashboard/src/components/DetailPanel.vue +68 -53
- package/packages/dashboard/src/components/DocPreview.vue +137 -20
- package/packages/dashboard/src/components/DocTree.vue +48 -26
- package/packages/dashboard/src/components/LogStream.vue +12 -32
- package/packages/dashboard/src/components/PipelineStage.vue +8 -8
- package/packages/dashboard/src/components/PipelineView.vue +35 -43
- package/packages/dashboard/src/components/ProjectList.vue +51 -77
- package/packages/dashboard/src/components/ProjectOverview.vue +178 -0
- package/packages/dashboard/src/components/StageBadge.vue +13 -13
- package/packages/dashboard/src/components/StepCard.vue +11 -11
- 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/main.js +4 -1
- package/packages/dashboard/src/style.css +14 -14
- package/src/index.js +55 -8
- package/src/init.js +69 -196
- package/src/migrate.js +1 -18
- package/src/progress.js +279 -281
- package/src/run.js +320 -0
- package/src/setup.js +1 -9
- package/src/stages/brainstorm.js +210 -0
- package/src/stages/execute.js +190 -0
- package/src/stages/index.js +22 -0
- package/src/stages/plan.js +118 -0
- package/src/stages/propose.js +115 -0
- package/src/stages/verify.js +98 -0
- package/packages/dashboard/dist/assets/index-hNnQCobe.css +0 -1
- package/packages/dashboard/dist/assets/index-qgPzQGjk.js +0 -17
- package/templates/archive.md +0 -121
- package/templates/brainstorm.md +0 -246
- package/templates/commit.md +0 -123
- package/templates/continue.md +0 -32
- package/templates/execute.md +0 -314
- package/templates/explore.md +0 -60
- package/templates/export.md +0 -21
- package/templates/init.md +0 -61
- package/templates/plan.md +0 -157
- package/templates/progress-format.md +0 -90
- package/templates/propose.md +0 -73
- package/templates/quick.md +0 -135
- package/templates/resume-dialog.md +0 -55
- package/templates/resume.md +0 -53
- package/templates/scan-quick.md +0 -49
- package/templates/skills/playwright-e2e/SKILL.md +0 -340
- package/templates/status.md +0 -72
- package/templates/verify.md +0 -253
- package/templates/workspace-sync.md +0 -89
- package/templates/workspace.md +0 -67
- /package/.sillyspec/{docs/sillyspec/brainstorm → changes/brainstorm-archive}/2026-04-05-dashboard-design.md +0 -0
- /package/.sillyspec/{docs/sillyspec/brainstorm → changes/brainstorm-archive}/2026-04-05-unified-docs-design.md +0 -0
- /package/.sillyspec/{specs/2026-04-05-dashboard-design.md → changes/dashboard/design.md.braindraft} +0 -0
- /package/.sillyspec/{specs/2026-04-05-unified-docs-design.md → changes/unified-docs-design/design.md} +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'fs'
|
|
2
|
+
|
|
3
|
+
export const definition = {
|
|
4
|
+
name: 'execute',
|
|
5
|
+
title: '波次执行',
|
|
6
|
+
description: '子代理并行 + 强制 TDD + 两阶段审查',
|
|
7
|
+
steps: [] // 动态构建,由 buildExecuteSteps() 生成
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// 固定前缀步骤定义
|
|
11
|
+
const fixedPrefix = [
|
|
12
|
+
{
|
|
13
|
+
name: '状态检查',
|
|
14
|
+
prompt: `检查当前状态,确认可以执行 execute。
|
|
15
|
+
|
|
16
|
+
### 操作
|
|
17
|
+
1. 运行 \`sillyspec progress show\`
|
|
18
|
+
2. 确认 currentStage 为 execute
|
|
19
|
+
3. 如果不是 → 检查是否有未完成的 tasks.md
|
|
20
|
+
4. 确认执行范围($ARGUMENTS 指定 wave/task 或全部)
|
|
21
|
+
|
|
22
|
+
### 输出
|
|
23
|
+
当前状态 + 执行范围确认`,
|
|
24
|
+
outputHint: '当前状态 + 执行范围',
|
|
25
|
+
optional: false
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: '加载上下文',
|
|
29
|
+
prompt: `加载计划、设计和代码库上下文。
|
|
30
|
+
|
|
31
|
+
### 操作
|
|
32
|
+
1. 读取 tasks.md(执行计划)
|
|
33
|
+
2. 读取 design.md(技术方案)
|
|
34
|
+
3. 读取 CONVENTIONS.md、ARCHITECTURE.md
|
|
35
|
+
4. 读取 local.yaml(构建命令)
|
|
36
|
+
5. 工作区模式:额外加载 CODEBASE-OVERVIEW.md
|
|
37
|
+
|
|
38
|
+
### 输出
|
|
39
|
+
已加载的上下文摘要`,
|
|
40
|
+
outputHint: '上下文摘要',
|
|
41
|
+
optional: false
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: '确认执行范围',
|
|
45
|
+
prompt: `解析任务,确认执行范围和确认模式。
|
|
46
|
+
|
|
47
|
+
### 操作
|
|
48
|
+
1. 从 plan 中解析 Wave 分组和任务列表
|
|
49
|
+
2. 根据任务描述关键词为每个 Task 建议模型:
|
|
50
|
+
- 架构/复杂推理 → 最强模型
|
|
51
|
+
- 常规实现 → 中等模型
|
|
52
|
+
- 简单修改 → 快速模型
|
|
53
|
+
- 文档/写作 → 写作模型
|
|
54
|
+
3. 用户在 tasks.md 中的 [model:xxx] 标签优先
|
|
55
|
+
4. 询问用户执行确认频率:
|
|
56
|
+
- 每个 Wave 确认 — 每个 Wave 完成后展示结果
|
|
57
|
+
- AI 自主判断 — BLOCKED 或计划外变更时才询问
|
|
58
|
+
- 全自动 — 全部自动执行
|
|
59
|
+
5. 查询知识库:读取 \`.sillyspec/knowledge/INDEX.md\`,根据 Task 关键词匹配
|
|
60
|
+
|
|
61
|
+
### 输出
|
|
62
|
+
Wave 分组 + 模型分配 + 确认模式 + 知识库匹配结果
|
|
63
|
+
|
|
64
|
+
### 注意
|
|
65
|
+
- 默认推荐"每个 Wave 确认"`,
|
|
66
|
+
outputHint: 'Wave 分组 + 模型分配',
|
|
67
|
+
optional: false
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
// 固定后缀步骤定义
|
|
72
|
+
const fixedSuffix = [
|
|
73
|
+
{
|
|
74
|
+
name: '知识库审阅',
|
|
75
|
+
prompt: `检查本轮执行产生的新知识。
|
|
76
|
+
|
|
77
|
+
### 操作
|
|
78
|
+
1. 检查 \`.sillyspec/knowledge/uncategorized.md\` 中待确认条目
|
|
79
|
+
2. 如有 → 提示用户审阅
|
|
80
|
+
3. 用户确认后改为 [已确认],可归类到专题文件
|
|
81
|
+
|
|
82
|
+
### 输出
|
|
83
|
+
新知识条目数量 + 审阅提示(或"无新知识")`,
|
|
84
|
+
outputHint: '知识条目数量',
|
|
85
|
+
optional: true
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: '完成确认',
|
|
89
|
+
prompt: `所有任务完成后的收尾。
|
|
90
|
+
|
|
91
|
+
### 操作
|
|
92
|
+
1. 询问用户下一步:
|
|
93
|
+
- 验证 → sillyspec run verify
|
|
94
|
+
- 归档 → /sillyspec:archive
|
|
95
|
+
- 继续开发
|
|
96
|
+
2. 提示 git 提交
|
|
97
|
+
|
|
98
|
+
### 输出
|
|
99
|
+
用户选择 + 下一步命令
|
|
100
|
+
|
|
101
|
+
### 注意
|
|
102
|
+
- 完成后运行 \`sillyspec run execute --done\` 即可自动推进阶段`,
|
|
103
|
+
outputHint: '用户选择',
|
|
104
|
+
optional: false
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 从 plan 文件解析 Wave 分组
|
|
110
|
+
*/
|
|
111
|
+
function parseWavesFromPlan(planContent) {
|
|
112
|
+
const waves = []
|
|
113
|
+
const lines = planContent.split('\n')
|
|
114
|
+
let currentWave = null
|
|
115
|
+
|
|
116
|
+
for (const line of lines) {
|
|
117
|
+
const waveMatch = line.match(/^#+\s*Wave\s+(\d+)/i)
|
|
118
|
+
if (waveMatch) {
|
|
119
|
+
currentWave = { index: parseInt(waveMatch[1]), tasks: [] }
|
|
120
|
+
waves.push(currentWave)
|
|
121
|
+
continue
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (currentWave) {
|
|
125
|
+
const taskMatch = line.match(/^[-*]\s*\[[ x]\]\s*(.+)/)
|
|
126
|
+
if (taskMatch) {
|
|
127
|
+
const fileMatch = taskMatch[1].match(/\(([^)]+)\)/)
|
|
128
|
+
currentWave.tasks.push({
|
|
129
|
+
name: taskMatch[1].replace(/\([^)]+\)/, '').trim(),
|
|
130
|
+
file: fileMatch ? fileMatch[1] : '未知'
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return waves
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 为 Wave 生成 prompt
|
|
141
|
+
*/
|
|
142
|
+
function buildWavePrompt(wave, waveIndex) {
|
|
143
|
+
const taskList = wave.tasks.map(t => `- [ ] ${t.name} (${t.file})`).join('\n')
|
|
144
|
+
return `## Wave ${waveIndex}: 执行以下任务
|
|
145
|
+
|
|
146
|
+
### 本 Wave 任务
|
|
147
|
+
${taskList}
|
|
148
|
+
|
|
149
|
+
### 执行要求
|
|
150
|
+
1. 按任务顺序执行,同一 Wave 内任务可并行
|
|
151
|
+
2. 铁律:先读后写、grep 确认方法存在、不编造、TDD
|
|
152
|
+
3. 每个任务完成后:
|
|
153
|
+
- 勾选 tasks.md 中对应 checkbox
|
|
154
|
+
- 记录改动文件和测试结果
|
|
155
|
+
4. 遇到 BLOCKED → 记录原因,选择:重试/跳过/停止
|
|
156
|
+
|
|
157
|
+
### 完成后
|
|
158
|
+
运行 sillyspec run execute --done --output "Wave ${waveIndex} 结果摘要"`
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 动态构建 execute 步骤列表
|
|
163
|
+
* @param {string|null} planFilePath - plan 文件路径,null 则用默认 3 Wave
|
|
164
|
+
* @returns {Array} 步骤列表
|
|
165
|
+
*/
|
|
166
|
+
export function buildExecuteSteps(planFilePath = null) {
|
|
167
|
+
let waves
|
|
168
|
+
|
|
169
|
+
if (planFilePath && existsSync(planFilePath)) {
|
|
170
|
+
const planContent = readFileSync(planFilePath, 'utf8')
|
|
171
|
+
waves = parseWavesFromPlan(planContent)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 如果没解析出 Wave,生成默认 3 个
|
|
175
|
+
if (!waves || waves.length === 0) {
|
|
176
|
+
waves = []
|
|
177
|
+
for (let i = 1; i <= 3; i++) {
|
|
178
|
+
waves.push({ index: i, tasks: [{ name: `默认任务 ${i}`, file: 'TBD' }] })
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const waveSteps = waves.map((wave, i) => ({
|
|
183
|
+
name: `Wave ${i + 1} 执行`,
|
|
184
|
+
prompt: buildWavePrompt(wave, i + 1),
|
|
185
|
+
outputHint: `Wave ${i + 1} 执行结果`,
|
|
186
|
+
optional: false
|
|
187
|
+
}))
|
|
188
|
+
|
|
189
|
+
return [...fixedPrefix, ...waveSteps, ...fixedSuffix]
|
|
190
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { definition as brainstorm } from './brainstorm.js'
|
|
2
|
+
import { definition as propose } from './propose.js'
|
|
3
|
+
import { definition as plan } from './plan.js'
|
|
4
|
+
import { definition as execute } from './execute.js'
|
|
5
|
+
import { definition as verify } from './verify.js'
|
|
6
|
+
|
|
7
|
+
export const stageRegistry = {
|
|
8
|
+
brainstorm,
|
|
9
|
+
propose,
|
|
10
|
+
plan,
|
|
11
|
+
execute,
|
|
12
|
+
verify
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// 阶段顺序,用于 getNextStage
|
|
16
|
+
const stageOrder = ['brainstorm', 'propose', 'plan', 'execute', 'verify']
|
|
17
|
+
|
|
18
|
+
export function getNextStage(currentStage) {
|
|
19
|
+
const index = stageOrder.indexOf(currentStage)
|
|
20
|
+
if (index === -1 || index >= stageOrder.length - 1) return null
|
|
21
|
+
return stageOrder[index + 1]
|
|
22
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export const definition = {
|
|
2
|
+
name: 'plan',
|
|
3
|
+
title: '实现计划',
|
|
4
|
+
description: '编写实现计划 — 2-5 分钟粒度,精确到文件路径和代码',
|
|
5
|
+
steps: [
|
|
6
|
+
{
|
|
7
|
+
name: '状态检查',
|
|
8
|
+
prompt: `检查当前状态,确认可以执行 plan。
|
|
9
|
+
|
|
10
|
+
### 操作
|
|
11
|
+
1. 运行 \`sillyspec progress show\`
|
|
12
|
+
2. 确认 currentStage 为 "plan"
|
|
13
|
+
|
|
14
|
+
### 输出
|
|
15
|
+
当前状态摘要`,
|
|
16
|
+
outputHint: '状态摘要',
|
|
17
|
+
optional: false
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: '加载上下文',
|
|
21
|
+
prompt: `加载所有规范文件和代码库上下文。
|
|
22
|
+
|
|
23
|
+
### 操作
|
|
24
|
+
1. 检测工作区模式
|
|
25
|
+
2. 读取 proposal.md、design.md、tasks.md、requirements.md
|
|
26
|
+
3. 读取 CONVENTIONS.md、ARCHITECTURE.md、STACK.md
|
|
27
|
+
4. 工作区模式:额外加载 CODEBASE-OVERVIEW.md + 各子项目上下文
|
|
28
|
+
|
|
29
|
+
### 输出
|
|
30
|
+
已加载的文件清单`,
|
|
31
|
+
outputHint: '文件清单',
|
|
32
|
+
optional: false
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: '锚定确认',
|
|
36
|
+
prompt: `确认已读取的文件。
|
|
37
|
+
|
|
38
|
+
### 操作
|
|
39
|
+
列出已读取的文件,标注存在/不存在。
|
|
40
|
+
|
|
41
|
+
### 输出
|
|
42
|
+
文件加载确认清单`,
|
|
43
|
+
outputHint: '文件确认清单',
|
|
44
|
+
optional: false
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: '逐任务展开',
|
|
48
|
+
prompt: `把 tasks.md 中每个 checkbox 展开为详细步骤。
|
|
49
|
+
|
|
50
|
+
### 操作
|
|
51
|
+
对每个 Task:
|
|
52
|
+
1. 标注精确文件路径(新建/修改/测试)
|
|
53
|
+
2. 每个步骤 2-5 分钟可完成
|
|
54
|
+
3. 包含完整可运行的代码示例
|
|
55
|
+
4. 包含验证命令和预期输出
|
|
56
|
+
5. 频繁 commit,每个任务独立提交
|
|
57
|
+
6. 引用已有代码的方法签名(从 CONVENTIONS.md 或源码获取)
|
|
58
|
+
|
|
59
|
+
### 输出
|
|
60
|
+
展开后的详细计划
|
|
61
|
+
|
|
62
|
+
### 注意
|
|
63
|
+
- 假设执行者是熟练开发者但对你项目零上下文
|
|
64
|
+
- 不要写"添加验证逻辑"这种模糊描述
|
|
65
|
+
- 要写"在 UserController.java 添加方法:public Result<UserVO> createUser(...)"
|
|
66
|
+
- 调用已有方法前必须 grep 确认存在`,
|
|
67
|
+
outputHint: '详细计划',
|
|
68
|
+
optional: false
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: '标注执行顺序',
|
|
72
|
+
prompt: `按依赖关系分组,标注执行顺序。
|
|
73
|
+
|
|
74
|
+
### 操作
|
|
75
|
+
1. 分析 Task 间依赖
|
|
76
|
+
2. 无依赖的 Task 归入同一 Wave(可并行)
|
|
77
|
+
3. 有依赖的 Task 按顺序排列
|
|
78
|
+
|
|
79
|
+
### 输出
|
|
80
|
+
Wave 分组列表 + 依赖说明
|
|
81
|
+
|
|
82
|
+
### 示例
|
|
83
|
+
Wave 1(并行):Task 1 + Task 2
|
|
84
|
+
Wave 2(依赖 Wave 1):Task 3
|
|
85
|
+
Wave 3(依赖 Wave 2):Task 4`,
|
|
86
|
+
outputHint: 'Wave 分组和依赖关系',
|
|
87
|
+
optional: false
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: '自检门控',
|
|
91
|
+
prompt: `自检计划质量。
|
|
92
|
+
|
|
93
|
+
### 操作
|
|
94
|
+
检查以下各项:
|
|
95
|
+
- [ ] 每个 task 有具体文件路径
|
|
96
|
+
- [ ] 每个 task 有验证命令和预期输出
|
|
97
|
+
- [ ] 已标注 Wave 和执行顺序
|
|
98
|
+
- [ ] plan 与 design.md 的文件变更清单一致
|
|
99
|
+
|
|
100
|
+
### 输出
|
|
101
|
+
自检通过/不通过`,
|
|
102
|
+
outputHint: '自检结果',
|
|
103
|
+
optional: false
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: '保存并更新进度',
|
|
107
|
+
prompt: `保存计划文件,更新进度。
|
|
108
|
+
|
|
109
|
+
### 操作
|
|
110
|
+
1. 保存到 \`.sillyspec/plans/YYYY-MM-DD-<change-name>.md\`
|
|
111
|
+
|
|
112
|
+
### 输出
|
|
113
|
+
计划文件路径 + 下一步命令`,
|
|
114
|
+
outputHint: '计划文件路径',
|
|
115
|
+
optional: false
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export const definition = {
|
|
2
|
+
name: 'propose',
|
|
3
|
+
title: '方案设计',
|
|
4
|
+
description: '生成结构化规范 — proposal + design + tasks',
|
|
5
|
+
steps: [
|
|
6
|
+
{
|
|
7
|
+
name: '状态检查',
|
|
8
|
+
prompt: `检查当前状态,确认可以执行 propose。
|
|
9
|
+
|
|
10
|
+
### 操作
|
|
11
|
+
1. 运行 \`sillyspec progress show\`
|
|
12
|
+
2. 确认 currentStage 为 "propose"
|
|
13
|
+
3. 如果没有设计文档 → 提示先运行 brainstorm
|
|
14
|
+
|
|
15
|
+
### 输出
|
|
16
|
+
当前状态摘要`,
|
|
17
|
+
outputHint: '状态摘要',
|
|
18
|
+
optional: false
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: '加载上下文',
|
|
22
|
+
prompt: `加载所有相关规范和代码库上下文。
|
|
23
|
+
|
|
24
|
+
### 操作
|
|
25
|
+
1. 检测工作区模式
|
|
26
|
+
2. 读取最新设计文档、需求文档、代码库约定
|
|
27
|
+
3. 如果是子阶段变更,读取 MASTER.md 和前序阶段设计
|
|
28
|
+
|
|
29
|
+
### 输出
|
|
30
|
+
已加载的文件列表`,
|
|
31
|
+
outputHint: '文件列表',
|
|
32
|
+
optional: false
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: '锚定确认',
|
|
36
|
+
prompt: `确认已读取的文件。
|
|
37
|
+
|
|
38
|
+
### 操作
|
|
39
|
+
1. 列出已读取的文件,标注存在/不存在
|
|
40
|
+
2. 格式:\`[x] 文件名 — 说明\` 或 \`[ ] 文件名 — 不存在(正常)\`
|
|
41
|
+
|
|
42
|
+
### 输出
|
|
43
|
+
文件加载确认清单
|
|
44
|
+
|
|
45
|
+
### 注意
|
|
46
|
+
- 文件不存在不是错误,正常标注即可`,
|
|
47
|
+
outputHint: '文件确认清单',
|
|
48
|
+
optional: false
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: '探索现有代码',
|
|
52
|
+
prompt: `理解相关模块的当前实现,识别影响范围。
|
|
53
|
+
|
|
54
|
+
### 操作
|
|
55
|
+
1. 根据设计文档中的文件变更清单,读取相关源码
|
|
56
|
+
2. 识别现有接口、方法签名、数据结构
|
|
57
|
+
3. 记录可能受影响的模块
|
|
58
|
+
|
|
59
|
+
### 输出
|
|
60
|
+
影响范围分析(涉及模块、需修改的文件、风险点)`,
|
|
61
|
+
outputHint: '影响范围分析',
|
|
62
|
+
optional: false
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: '生成规范文件',
|
|
66
|
+
prompt: `在 \`.sillyspec/changes/<变更名>/\` 下生成四个文件。
|
|
67
|
+
|
|
68
|
+
### 操作
|
|
69
|
+
1. 生成 proposal.md:动机、变更范围、不在范围内、成功标准
|
|
70
|
+
2. 生成 requirements.md:功能需求、用户场景(Given/When/Then)、非功能需求
|
|
71
|
+
3. 生成 design.md:架构决策、文件变更清单、数据模型、API 设计、代码风格参照
|
|
72
|
+
4. 生成 tasks.md:任务列表(只列名称,不展开步骤)
|
|
73
|
+
|
|
74
|
+
### 输出
|
|
75
|
+
四个文件路径
|
|
76
|
+
|
|
77
|
+
### 注意
|
|
78
|
+
- 表名/字段名必须来自真实 schema 或标注"新增"
|
|
79
|
+
- 用户场景必须用 Given/When/Then 格式
|
|
80
|
+
- tasks.md 只列任务名,细节在 plan 阶段展开`,
|
|
81
|
+
outputHint: '四个文件路径',
|
|
82
|
+
optional: false
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: '自检门控',
|
|
86
|
+
prompt: `自检生成的规范文件。
|
|
87
|
+
|
|
88
|
+
### 操作
|
|
89
|
+
检查以下各项:
|
|
90
|
+
- [ ] proposal.md 有动机、变更范围、不在范围内、成功标准
|
|
91
|
+
- [ ] design.md 有文件变更清单表格
|
|
92
|
+
- [ ] requirements.md 有 Given/When/Then 用户场景
|
|
93
|
+
- [ ] tasks.md 每个 task 有文件路径
|
|
94
|
+
|
|
95
|
+
任何不通过 → 修正后重新检查。
|
|
96
|
+
|
|
97
|
+
### 输出
|
|
98
|
+
自检通过/不通过`,
|
|
99
|
+
outputHint: '自检结果',
|
|
100
|
+
optional: false
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: '展示并更新进度',
|
|
104
|
+
prompt: `展示规范给用户,更新进度。
|
|
105
|
+
|
|
106
|
+
### 操作
|
|
107
|
+
1. 展示 proposal.md 和 design.md 摘要
|
|
108
|
+
|
|
109
|
+
### 输出
|
|
110
|
+
展示结果 + 下一步命令`,
|
|
111
|
+
outputHint: '展示结果',
|
|
112
|
+
optional: false
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export const definition = {
|
|
2
|
+
name: 'verify',
|
|
3
|
+
title: '验证确认',
|
|
4
|
+
description: '对照规范检查 + 测试套件',
|
|
5
|
+
steps: [
|
|
6
|
+
{
|
|
7
|
+
name: '状态检查',
|
|
8
|
+
prompt: `检查当前状态,确认可以执行 verify。
|
|
9
|
+
|
|
10
|
+
### 操作
|
|
11
|
+
1. 运行 \`sillyspec progress show\`
|
|
12
|
+
2. 确认 currentStage 为 "verify"
|
|
13
|
+
|
|
14
|
+
### 输出
|
|
15
|
+
当前状态摘要`,
|
|
16
|
+
outputHint: '状态摘要',
|
|
17
|
+
optional: false
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: '加载规范并锚定',
|
|
21
|
+
prompt: `加载规范文件并确认。
|
|
22
|
+
|
|
23
|
+
### 操作
|
|
24
|
+
1. 读取 proposal.md、design.md、tasks.md、requirements.md
|
|
25
|
+
2. 标注每个文件的存在/不存在状态
|
|
26
|
+
|
|
27
|
+
### 输出
|
|
28
|
+
文件加载确认清单`,
|
|
29
|
+
outputHint: '文件确认清单',
|
|
30
|
+
optional: false
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: '逐项检查任务',
|
|
34
|
+
prompt: `对照 tasks.md 检查每个任务完成状态。
|
|
35
|
+
|
|
36
|
+
### 操作
|
|
37
|
+
对每个 checkbox:
|
|
38
|
+
1. 检查相关文件是否存在
|
|
39
|
+
2. 检查代码是否实现了描述的功能
|
|
40
|
+
3. 标记:✅ 已完成 / ❌ 未完成 / ⚠️ 部分完成
|
|
41
|
+
|
|
42
|
+
### 输出
|
|
43
|
+
任务完成度列表 + 完成率
|
|
44
|
+
|
|
45
|
+
### 注意
|
|
46
|
+
- 不修改任何代码,只做检查和报告`,
|
|
47
|
+
outputHint: '任务完成度报告',
|
|
48
|
+
optional: false
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: '对照设计检查',
|
|
52
|
+
prompt: `对照 design.md 检查实现一致性。
|
|
53
|
+
|
|
54
|
+
### 操作
|
|
55
|
+
1. 架构决策是否遵循
|
|
56
|
+
2. 文件变更清单是否一致
|
|
57
|
+
3. 数据模型是否符合
|
|
58
|
+
4. API 设计是否符合
|
|
59
|
+
|
|
60
|
+
### 输出
|
|
61
|
+
一致性检查结果`,
|
|
62
|
+
outputHint: '设计一致性报告',
|
|
63
|
+
optional: false
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: '运行测试和质量扫描',
|
|
67
|
+
prompt: `运行完整测试套件和代码质量扫描。
|
|
68
|
+
|
|
69
|
+
### 操作
|
|
70
|
+
1. 运行测试:\`pnpm test\` 或 \`npm test\` 或 \`pytest\`
|
|
71
|
+
2. 记录通过/失败数量,分析失败原因
|
|
72
|
+
3. 搜索技术债务:grep TODO/FIXME/HACK/XXX
|
|
73
|
+
4. 运行综合校验(lint、测试等)
|
|
74
|
+
|
|
75
|
+
### 输出
|
|
76
|
+
测试结果 + 技术债务标记`,
|
|
77
|
+
outputHint: '测试结果 + 技术债务',
|
|
78
|
+
optional: false
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: '输出验证报告',
|
|
82
|
+
prompt: `生成完整验证报告。
|
|
83
|
+
|
|
84
|
+
### 操作
|
|
85
|
+
1. 汇总以上所有检查结果
|
|
86
|
+
2. 给出结论:PASS / PASS WITH NOTES / FAIL
|
|
87
|
+
|
|
88
|
+
### 输出
|
|
89
|
+
验证报告 markdown + 下一步命令
|
|
90
|
+
|
|
91
|
+
### 注意
|
|
92
|
+
- PASS → 下一步 archive
|
|
93
|
+
- FAIL → 修复后重新 verify`,
|
|
94
|
+
outputHint: '验证报告',
|
|
95
|
+
optional: false
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.slide-enter-active[data-v-bcd9d503],.slide-leave-active[data-v-bcd9d503]{transition:all .2s ease}.slide-enter-from[data-v-bcd9d503],.slide-leave-to[data-v-bcd9d503]{opacity:0;max-height:0;overflow:hidden}.slide-enter-to[data-v-bcd9d503],.slide-leave-from[data-v-bcd9d503]{max-height:300px}.line-clamp-2[data-v-361aba6a]{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.backdrop-enter-active[data-v-f8e1b53e],.backdrop-leave-active[data-v-f8e1b53e]{transition:opacity .15s ease}.backdrop-enter-from[data-v-f8e1b53e],.backdrop-leave-to[data-v-f8e1b53e]{opacity:0}.palette-enter-active[data-v-f8e1b53e],.palette-leave-active[data-v-f8e1b53e]{transition:all .2s cubic-bezier(.16,1,.3,1)}.palette-enter-from[data-v-f8e1b53e],.palette-leave-to[data-v-f8e1b53e]{opacity:0;transform:translate(-50%,-8px) scale(.98)}*{margin:0;padding:0;box-sizing:border-box}body{font-family:DM Sans,-apple-system,BlinkMacSystemFont,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#app{width:100vw;height:100vh;overflow:hidden}/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--animate-pulse-dot:pulse-dot 1.5s ease-in-out infinite}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-\[18\%\]{top:18%}.bottom-0{bottom:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.-mt-0\.5{margin-top:calc(var(--spacing) * -.5)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.flex{display:flex}.hidden{display:none}.inline-flex{display:inline-flex}.h-1{height:calc(var(--spacing) * 1)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-\[2px\]{height:2px}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:calc(var(--spacing) * 32)}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-72{max-height:calc(var(--spacing) * 72)}.w-0{width:calc(var(--spacing) * 0)}.w-1{width:calc(var(--spacing) * 1)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-14{width:calc(var(--spacing) * 14)}.w-20{width:calc(var(--spacing) * 20)}.w-32{width:calc(var(--spacing) * 32)}.w-\[2px\]{width:2px}.w-\[200px\]{width:200px}.w-\[340px\]{width:340px}.w-full{width:100%}.w-px{width:1px}.w-screen{width:100vw}.max-w-md{max-width:var(--container-md)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse-dot{animation:var(--animate-pulse-dot)}.cursor-col-resize{cursor:col-resize}.cursor-pointer{cursor:pointer}.resize{resize:both}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-px>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(1px * var(--tw-space-y-reverse));margin-block-end:calc(1px * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-none{--tw-border-style:none;border-style:none}.bg-transparent{background-color:#0000}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-3{padding:calc(var(--spacing) * 3)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-px{padding-block:1px}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pb-0{padding-bottom:calc(var(--spacing) * 0)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pl-3\.5{padding-left:calc(var(--spacing) * 3.5)}.pl-\[3px\]{padding-left:3px}.text-center{text-align:center}.text-left{text-align:left}.font-\[DM_Sans\,sans-serif\]{font-family:DM Sans,sans-serif}.font-\[JetBrains_Mono\,monospace\]{font-family:JetBrains Mono,monospace}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.2em\]{--tw-tracking:.2em;letter-spacing:.2em}.tracking-\[0\.15em\]{--tw-tracking:.15em;letter-spacing:.15em}.tracking-\[0\.25em\]{--tw-tracking:.25em;letter-spacing:.25em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.whitespace-pre-wrap{white-space:pre-wrap}.text-black{color:var(--color-black)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.opacity-0{opacity:0}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:bg-\[\#FBBF24\]:hover{background-color:#fbbf24}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab,var(--color-white) 5%,transparent)}}}.active\:bg-\[\#FBBF24\]:active{background-color:#fbbf24}}@keyframes pulse-glow{0%,to{box-shadow:0 0 #fbbf2466}50%{box-shadow:0 0 12px 2px #fbbf2426}}@keyframes pulse-dot{0%,to{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(1.5)}}@keyframes breathe{0%,to{opacity:.5}50%{opacity:1}}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}@keyframes slide-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes glow-border{0%,to{border-color:#fbbf2426}50%{border-color:#fbbf2480}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-3px)}}.font-mono-log{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}.noise-bg{position:relative}.noise-bg:before{content:"";pointer-events:none;z-index:0;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");position:absolute;top:0;right:0;bottom:0;left:0}.accent-stripe{background:repeating-linear-gradient(-45deg,#0000,#0000 8px,#fbbf2408 8px,#fbbf2408 9px)}.progress-gradient{background:linear-gradient(90deg,#fbbf24,#f59e0b,#fb923c)}.skeleton-shimmer{background:linear-gradient(90deg,#1a1e28 25%,#2a3040,#1a1e28 75%) 0 0/200% 100%;animation:1.5s ease-in-out infinite shimmer}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:#2a3040;border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#3a4555}*{scrollbar-width:thin;scrollbar-color:#2a2a2d transparent}::selection{color:#fbbf24;background:#fbbf2433}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}
|